相关文章:
Java8 中的一个重要特性就是支持了 lambda 表达式,所谓 lambda 表达式可以简单地理解为传递匿名函数的一种方式,它没有名称,但有参数列表、函数主体、返回类型,可能还有一个可以抛出的异常列表,有以下几点特点:
-
匿名
- lambda 表达式不想普通方法那样拥有一个明确的名称
-
函数
- lambda 表达式不想普通方法那样属于某个特定的类,但和方法相同的是,lambda 表达式也有参数列表、函数主体、返回类型,以及可能还有一个可以抛出的异常列表
-
传递
- lambda 表达式可以作为参数传递给方法或存储在变量中
-
简洁
- lambda 表达式无需像匿名内部类一样写很多模板代码
一、使用局部变量
-
当在 lambda 表达式中使用局部变量时,该变量必须显示地声明为 final,否则代码将无法编译
-
相关解释
-
Apple.java
public class Apple { private String color; private Integer weight; public Apple(String color, Integer weight) { this.color = color; this.weight = weight; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public Integer getWeight() { return weight; } public void setWeight(Integer weight) { this.weight = weight; } @Override public String toString() { return "Apple{" + "color='" + color + '\'' + ", weight=" + weight + '}'; } }
二、方法引用
-
方法引用可以让我们重复使用现有的方法定义,根据已有的方法来创建 lambda 表达式
-
当我们使用方法引用时,目标引用放在分隔符
::
前面,方法名称放在::
后面,如:Apple::getWeight
就是引用了 Apple 类中定义的方法 getWeight (不需要括号),是 lambda 表达式(Apple apple) -> apple.getWeight()
的快捷写法List<String> list = Arrays.asList("C", "a", "d", "B"); list.sort(String::compareTo); // [B, C, a, d] System.out.println(list); list.sort(String::compareToIgnoreCase); System.out.println(list); // [a, B, C, d]
-
方法引用主要有三类
-
指向静态方法的方法引用
Integer::parseInt
-
指向任意类型实例方法的方法引用
String::length
-
指向现有对象的实例方法的方法引用
Apple apple = new Apple(); Consumer<String> consumer = apple::setColor;
-
三、构造函数引用
-
对于一个现有的构造函数,我们可以利用它的名称和关键字 new 来创建一个它的引用,如:
ClassName::new
,它的功能与指向静态方法的引用类似-
无参构造
Supplier<Apple> supplier = Apple::new; Apple apple = supplier.get(); // 等价于 Supplier<Apple> supplier = () -> new Apple(); Apple apple = supplier.get();
-
有参构造(构造函数签名为:Apple(String color))
Function<String, Apple> function = Apple::new; Apple apple = function.apply("red"); // 等价于 Function<String, Apple> function = str -> new Apple(); Apple apple = function.apply("red");
-
有参构造(构造函数签名为:Apple(String color, Integer weight))
BiFunction<String, Integer, Apple> biFunction = Apple::new; Apple apple = biFunction.apply("red", 15); // 等价于 BiFunction<String, Integer, Apple> biFunction = (color, weight) -> new Apple(color, weight); Apple apple = biFunction.apply("red", 15);
-
四、使用 lambda 表达式
-
比较器复合
List<Apple> inventory = new ArrayList<>(Arrays.asList( new Apple("red", 15), new Apple("green", 10), new Apple("blue", 25), new Apple("black", 20))); // 正序 inventory.sort(Comparator.comparing(Apple::getWeight)); // [Apple{color='red', weight=10}, Apple{color='red', weight=15}, // Apple{color='black', weight=20}, Apple{color='blue', weight=25}] System.out.println(inventory); // 倒序 inventory.sort(Comparator.comparing(Apple::getWeight).reversed()); // [Apple{color='blue', weight=25}, Apple{color='black', weight=20}, // Apple{color='red', weight=15}, Apple{color='red', weight=10}] System.out.println(inventory);
-
谓词复合
-
过滤方法
public static List<Apple> filterApples(List<Apple> inventory, ApplePredicate predicate) { List<Apple> result = new ArrayList<>(); inventory.forEach(apple -> { if (predicate.test(apple)) { result.add(apple); } }); return result; }
-
negate (非)
List<Apple> inventory = new ArrayList<>(Arrays.asList( new Apple("red", 15), new Apple("red", 10), new Apple("blue", 25), new Apple("black", 20))); // 筛选出不是红色的苹果 Predicate<Apple> redApplePredicate = apple -> "red".equals(apple.getColor()); List<Apple> appleList = filterApples(inventory, redApplePredicate.negate()); // [Apple{color='blue', weight=25}, Apple{color='black', weight=20}] System.out.println(appleList);
-
and (且)
List<Apple> inventory = new ArrayList<>(Arrays.asList( new Apple("red", 15), new Apple("red", 10), new Apple("blue", 25), new Apple("black", 20))); // 筛选出重量大于 10g 的红苹果 Predicate<Apple> redApplePredicate = apple -> "red".equals(apple.getColor()); Predicate<Apple> weightPredicate = apple -> apple.getWeight() > 10; List<Apple> appleList = filterApples(inventory, redApplePredicate.and(weightPredicate)); // [Apple{color='red', weight=15}] System.out.println(appleList);
-
or (或)
List<Apple> inventory = new ArrayList<>(Arrays.asList( new Apple("red", 15), new Apple("red", 10), new Apple("blue", 25), new Apple("black", 20))); // 筛选出红苹果或重量大于20g的苹果 Predicate<Apple> redApplePredicate = apple -> "red".equals(apple.getColor()); Predicate<Apple> weightPredicate = apple -> apple.getWeight() > 20; List<Apple> appleList = filterApples(inventory, redApplePredicate.or(weightPredicate)); // [Apple{color='red', weight=15}, Apple{color='red', weight=10}, Apple{color='blue', weight=25}] System.out.println(appleList);
-
-
函数复合
-
andThen
-
返回一个组合函数,先对输入应用第一个函数,再对输出应用第二个函数 (先加后乘)
// 先运算 1+1=2,再运算 2*2=4 Function<Integer, Integer> plus = x -> x + 1; Function<Integer, Integer> mult = x -> x * 2; Function<Integer, Integer> andThen = plus.andThen(mult); System.out.println(andThen.apply(1)); // 4
-
-
compose
-
返回一个组合函数,先对输入应用第二个函数,再对输出应用第一个函数 (先乘后加)
// 先运算 1*2=2,再运算 2+1=3 Function<Integer, Integer> plus = x -> x + 1; Function<Integer, Integer> mult = x -> x * 2; Function<Integer, Integer> compose = plus.compose(mult); System.out.println(compose.apply(1)); // 3
-
-