方法參考

方法引用允許遵循相容功能介面的預定義靜態或例項方法作為引數而不是匿名 lambda 表示式傳遞。

假設我們有一個模型:

class Person {
    private final String name;
    private final String surname;

    public Person(String name, String surname){
        this.name = name;
        this.surname = surname;
    }

    public String getName(){ return name; }
    public String getSurname(){ return surname; }
}

List<Person> people = getSomePeople();

例項方法引用(對任意例項)

people.stream().map(Person::getName)

等價的 lambda:

people.stream().map(person -> person.getName())

在此示例中,正在傳遞對 Person 型別的例項方法 getName() 的方法引用。由於它已知是集合型別,因此將呼叫例項上的方法(稍後知道)。

例項方法引用(對特定例項)

people.forEach(System.out::println);

由於 System.outPrintStream 的一個例項,因此將對此特定例項的方法引用作為引數傳遞。

等價的 lambda:

people.forEach(person -> System.out.println(person));

靜態方法參考

同樣,對於轉換流,我們可以應用對靜態方法的引用:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
numbers.stream().map(String::valueOf)

此示例傳遞對 String 型別的靜態 valueOf() 方法的引用。因此,集合中的例項物件作為引數傳遞給 valueOf()

等價的 lambda:

 numbers.stream().map(num -> String.valueOf(num))

引用建構函式

List<String> strings = Arrays.asList("1", "2", "3");
strings.stream().map(Integer::new)

閱讀將流的元素收集到集合中以檢視如何收集要收集的元素。

這裡使用 Integer 型別的單個 String 引數建構函式,在給定作為引數提供的字串的情況下構造整數。在這種情況下,只要字串表示數字,流就會對映到整數。等價的 lambda:

strings.stream().map(s -> new Integer(s));

備忘單

方法參考格式 等價的 Lambda
靜態方法 TypeName::method (args) -> TypeName.method(args)
非靜態方法(例如 * instance::method (args) -> instance.method(args)
非靜態方法(無例項) TypeName::method (instance, args) -> instance.method(args)
建構函式 ** TypeName::new (args) -> new TypeName(args)
陣列建構函式 TypeName[]::new (int size) -> new TypeName[size]

* instance 可以是任何評估為對例項的引用的表示式,例如 getInstance()::methodthis::method

** 如果 TypeName 是非靜態內部類,則建構函式引用僅在外部類例項的範圍內有效