
u=3305436623,3058662916&fm=26&gp=0.jpg
Lambda表达式可以理解为匿名函数的一种方式:
- 匿名 -- 说匿名,是因为它不像普通的方法那样有一个明确的方法名称
- 函数 -- 说它是函数,是因为Lambda函数不像方法那样属于某一个特定的类,但是和方法一样,Lambda有参数列表,函数主体,返回类型,还可能有抛出的异常列表
- 传递 -- 可以作为参数传递给方法或者存储在变量中
- 简洁 -- 无需向匿名类那样写很多的模板代码
Lambda表达式由参数、箭头、主体组成
匿名:
Comparator<Apple> byWeight = new Comparator<Apple>() {
public int compare(Apple a1, Apple a2){
return a1.getWeight().compareTo(a2.getWeight());
}
};
Lambda表达式:
Comparator<Apple> byWeight =
(Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
或者
Comparator<Apple> byWeight =
(Apple a1, Apple a2) -> {
return a1.getWeight().compareTo(a2.getWeight());
}
错误示例
//return 是一个控制流语句,需要使用{}
(Apple a1, Apple a2) -> return a1.getWeight().compareTo(a2.getWeight());
方法引用
之前
inventory.sort((Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight()));
之后(使用方法引用和java.util.Comparator.comparing):
inventory.sort(comparing(Apple::getWeight));
复合Lambda表达式的用法
- 比较器复合
1.逆序
//按重量递减排序
inventory.sort(comparing(Apple::getWeight).reversed());
2.比较器链
//thenComparing方法接受一个函数做参数,如果两个对象用第一个Comparator比较之后是一样的,就提供第二个Cpmparator进行比较
inventory.sort(comparing(Apple::getWeight).reversed().thenComparing(Apple::getCountry));
- 谓词复合
谓词接口包含三个方法:negate,and,or
//产生现有Predicate对象redApple的非
Predicate<Apple> notRedApple = redApple.negate();
链接两个谓词来生成另一个Predicate对象
Predicate<Apple> redAndHeavyApple = redApple.and(a -> a.getWeight() > 150);
链接Predicate的方法来构造更复杂Predicate对象
Predicate<Apple> redAndHeavyAppleOrGreen = redApple.and(a -> a.getWeight() > 150).or(a -> "green".equals(a.getColor()));
and 和 or方法是按照在表达式链中的位置,从左向右确定优先级的,因此,a.or(b).and(c) 等价于
(a || b)&& c
- 函数复合
Function接口提供了andThen和compose两个默认方法,他们都会返回一个Function的一个实例
Function<Integer, Integer> f = x -> x + 1;
Function<Integer, Integer> g = x -> x * 2;
Function<Integer, Integer> h = f.andThen(g); // 等价于数学表达式 g(f(x))
Function<Integer, Integer> m = f.compose(g); // 等价于数学表达式 f(g(x))
int result = h.apply(1); //结果为4
int result1 = m.apply(1); //结果为3