Lambda方法引用
作者:互联网
inventory.sort((Apple c1, Apple c2) -> c1.getWeight().compareTo(c2.getWeight()));
与下面的代码是等同的
inventory.sort(Comparator.comparing(Apple::getWeight));
这里把(Apple c1, Apple c2) -> c1.getWeight().compareTo(c2.getWeight()) 简化成了Comparator.comparing(Apple::getWeight()),这种写法被专家们认为更自然、更易读。完整代码如下:
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())); } }
同样推展:
(Apple a) -> a.getWeight() ====> Apple::getWeight
() -> Thread.currentThread().dumpStack() ====> Thread.currentThread()::dumpStack
(str, i) -> str.substring(i) ====> String.substring
(String s) -> System.out.println(s) ====> System.out::println
这里面分涉及到如下几种类别:
(1)静态方法的引用
Integer::parseInt,其中parseInt()为Integer类的静态方法
(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);
标签:String,weight,System,引用,println,Lambda,方法,getWeight,Apple 来源: https://blog.51cto.com/qingkechina/2554685