Lambda方法引用

inventory.sort((Apple c1, Apple c2) -> c1.getWeight().compareTo(c2.getWeight()));

與下面的代碼是等同的java

inventory.sort(Comparator.comparing(Apple::getWeight));


這裏把(Apple c1, Apple c2) -> c1.getWeight().compareTo(c2.getWeight()) 簡化成了Comparator.comparing(Apple::getWeight()),這種寫法被專家們認爲更天然、更易讀。完整代碼以下:app

package com.qingke.chapter2;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class Lambda { public static void main(String[] args) {
        List<Apple> inventory = new ArrayList<>();
        Apple a1 = new Apple();
        a1.setColor("green");
        a1.setWeight(48);
        Apple a2 = new Apple();
        a2.setColor("red");
        a2.setWeight(89);
        Apple a3 = new Apple();
        a3.setColor("green");
        a3.setWeight(79);
        inventory.add(a1);
        inventory.add(a2);
        inventory.add(a3);

        inventory.sort(Comparator.(Apple::getWeight));

        inventory.stream().forEach( (Apple p) -> System..println(p.getWeight() + " " + p.getColor()));
    }
}


一樣推展:ide

(Apple a) -> a.getWeight()   ====>    Apple::getWeight函數

() -> Thread.currentThread().dumpStack()   ====>   Thread.currentThread()::dumpStackthis

(str, i) -> str.substring(i)   ====>  String.substringspa

(String s) -> System.out.println(s)   ====>   System.out::println對象

這裏面分涉及到以下幾種類別:字符串

(1)靜態方法的引用 get

         Integer::parseInt,其中parseInt()爲Integer類的靜態方法string

(2)對象(類的實例對象)方法的引用

         Transaction expensiveTransaction = .....;

         expensiveTransaction::getValue,其中expensiveTransaction爲Transaction類的一個實例,getValue()爲Transaction的方法

(3)指向任意類型實例方法的引用

         這個比較難理解,

         相似String::length,你在引用一個對象的方法,而這個對象自己是Lambda的一個參數; 

         再如,(String s) -> s.toUpperCase()   ====>   String::toUpperCase

第(2)和第(3)的區別在於,(2)是Lambda表達式以外的對象方法引用、(3)是Lambda表達式以內的對象方法引用


List<String> str = Arrays.("a", "A", "b", "B", "E", "D");
str.sort((s1, s2) -> s1.compareToIgnoreCase(s2)); 
str.stream().forEach((s) -> System..println(s));

上面能夠是按描述來調用,Java8更指望是按方法來調用,因此修改成:

List<String> str = Arrays.("a", "A", "b", "B", "E", "D");
str.sort(String::compareToIgnoreCase);
str.stream().forEach(System.::println);


再例如:把字符串類型的數字轉換爲數字型的數字

Function<String, Integer>  = (String s) -> Integer.(s);
System..println(.apply("8"));

按方法引用可修改成:

Function<String, Integer> stringToInteger = 
System..println(stringToInteger.apply("8"));


再例如:判斷集合中是否有該元素

BiPredicate<List<String>, String> contains = ;
List<String> strList = Arrays.("a", "b", "china", "love", "c", "demo");
System..println(contains.test(strList, "china"));

按方法引用可修改成:

BiPredicate<List<String>, String> contains = ;
List<String> strList = Arrays.("a", "b", "china", "love", "c", "demo");
System..println(contains.test(strList, "china"));


2. 構造函數引用

咱們之前定義一個Apple類,若對類進行初始化一般會這樣操做:

public class Apple {
    private String color;

    private int weight;

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }
}

Apple a = new Apple();

這樣經過Apple的實例對象a就能夠去幹活了。但自從引入了Lambda以後,咱們也能夠這樣操做:

Supplier<Apple> c1 = () -> new Apple(); 
Apple a = c1.get();

這裏使用了描述符:() -> new Apple()來生成對象,固然這裏再講構造器函數引用,因此上面可修改成:

Supplier<Apple> c1 = ;
Apple a = c1.get();


若是Apple的構造函數是:

public Apple(int weight){ // 帶參數

     this.weight = weight;

}

則構造函數引用能夠這樣寫:

Function<Integer, Apple> c2 = Apple::new;
Apple a2 = c2.apply(110);

它等價於:

Function<Integer, Apple> c2 = (weight) -> new Apple(weight);

Apple a2 = c2.apply(110);

相關文章
相關標籤/搜索