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