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);