Java8特性之'::' 關鍵字

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.csdn.net/kegaofei/article/details/80582356

`

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章