Java8中提供了::,使我们可以直接访问类的构造函数,静态函数,对象函数。
首选我们构造一个类Product
public class Product {
private long id;
private String name;
private BigDecimal price;
public Product(){}
public Product(int id,String name,BigDecimal price){
this.id=id;
this.name=name;
this.price=price;
}
public Product(int id){
this.id=id;
}
public Product(String name){
this.name=name;
}
public long getId() { return id; }
public void setId(long id) {this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public BigDecimal getPrice() {return price; }
public void setPrice(BigDecimal price) {this.price = price; }
/*获取明细*/
public static String getDetails(Product product){
return product.id+" "+product.name+" 售价:"+product.price.toString();
}
/*模拟获取一个新对象*/
public static Product getNewProduct(Product product){
product.setName(product.getName()+"new");
return product;
}
}
如何用 ‘::’ 来访问类Something中的方法呢?先定义一个接口,因为必须要用 functional interface 来接收,否则编译错误(The target type of this expression must be a functional interface)
@FunctionalInterface
public interface IConvert<T,F> {
T convert(F form);
}
我们给一个数据集,方便测试。
String no="ABCDEFGHIJK";
List<Product> list=new ArrayList<>();
for(int i=0;i<10;i++){
Product product=new Product();
product.setId(i);
product.setName("蒙牛"+no.substring(i,i+1));
//TODO 可以采用nextLong,nexInt方式或随机值
product.setPrice(new BigDecimal((int)(Math.random()*100)));
list.add(product);
}
准备完毕,开始测试。
1、首先我们来一段rap,嘿嘿,首先我们来一段 【::】简单的运用
list.sort(Comparator.comparing(Product::getPrice));
System.out.println(jsonToString(list));
他可以在排序上如上使用,此代码也等价于
list.sort(Comparator.comparing(product-> product.getPrice()));
执行结果:
[{“id”:8,“name”:“蒙牛I”,“price”:11},{“id”:1,“name”:“蒙牛B”,“price”:14},{“id”:5,“name”:“蒙牛F”,“price”:18},{“id”:6,“name”:“蒙牛G”,“price”:33},{“id”:7,“name”:“蒙牛H”,“price”:57},{“id”:2,“name”:“蒙牛C”,“price”:58},{“id”:9,“name”:“蒙牛J”,“price”:64},{“id”:4,“name”:“蒙牛E”,“price”:78},{“id”:0,“name”:“蒙牛A”,“price”:83},{“id”:3,“name”:“蒙牛D”,“price”:88}]
2、对静态方法的调用
参数1是返回类型,参数2是传参类型
IConvert<String,Product> doSomeThing2=Product::getDetails;
System.out.println(doSomeThing2.convert(list.get(0)));
执行结果:
8 蒙牛I 售价:11
3、对对象方法的调用
参数1是返回类型,参数2是传参类型
IConvert<String,Product> doSomeThing1=Product::getName;
System.out.println(doSomeThing1.convert(list.get(0)));
蒙牛I
4、对构造函数的使用
对方法的匹配上,遵循就近原则
(1)返回值为实体模型,传参为整型
IConvert<Product,Integer> doSomeThing4=Product::new;
System.out.println(jsonToString(doSomeThing4.convert(1)));
执行结果:
{"id":1}
(2)返回值为实体模型,传参为字符串
IConvert<Product,String> doSomeThing5=Product::new;
System.out.println(jsonToString(doSomeThing5.convert("光明乳业")));
执行结果:
{“id”:0,“name”:“光明乳业”}
(3)返回实体模型,穿多个参数
为了满足传递多个参数的需求,我们构建第二个接口
@FunctionalInterface
public interface IConvert2<T,I,J,K> {
T convert(I p1,J p2,K p3);
}
下面的代码是具体实现:
IConvert2<Product,Integer,String,BigDecimal> doSomeThing6=Product::new;
System.out.println(jsonToString(doSomeThing6.convert(100,"光明乳业",new BigDecimal(99.8f))));
输出:
//TODO 为什么这里的价格输出值是?
{“id”:100,“name”:“光明乳业”,“price”:99.8000030517578125}
【::】关键字的作用
1、可以节省代码,如使用方式【1】,是代码更简洁
2、与@FunctionalInterface接口联用,可以当做模板来使用。
思考:【::】关键字与c++中的函数指针的关联?
参考文章:https://blog.youkuaiyun.com/kegaofei/article/details/80582356
`