Lambda表达式
类型检查、类型推断以及限制
1.1类型检查
Lambda的类型是从使用Lambda的上下文推断出来的。
List<Apple> heavierThan150g=filter(inventory,(Apple a) -> a.getWeight()>150)
1.首先找出filter的方法声明;
2.要求他是Predicate<Apple>(目标类型) 对象的第二个正式参数;
3.Preciate<Apple>是一个函数式接口,定义了一个叫做test的抽象方法;
4.test方法描述了一个函数描述符,他可以接受一个Apple,并返回一个boolean;
5.filter的任何参数都必须匹配这个要求;
1.2同样的Lambda,不同的函数式接口
只要抽象方法签名能够兼容,同一个Lambda可以与不同的函数式接口联系起来。
Callable<Integer> c = () -> 42;
PrivilegedAction<Integer> = () -> 42;
他们的签名都式 ()-> int
1.3类型推断
Comparator<Apple> c = (Apple a1,Apple a2) -> a1.getWeight().compareTo(a2.getWeight()) //没有类型推断
Comparator<Apple> c = (a1,Aa2) -> a1.getWeight().compareTo(a2.getWeight()) //有类型推断
注意:有时候显示写出类型更易读,有时候去掉更易读,没有哪一种绝对的好。
1.4使用局部变量
Lambda允许使用自由变量(就是外层作用域中的变量)
int portNumber = 1000;
Runnable r = () -> System.out.println(portNumber);
portNumber = 1200;
注释:以上代码编译会报错,因为Lambda表达式引用的局部变量必须是最终的(final).
方法引用
2.1概念
方法引用可以被看作是仅仅调用特定方法的Lambda的一种快捷写法。可以看作是一种“语法糖”,让Lambda看起来更简洁。
方法引用主要有三类
(1)指向静态方法的方法引用(例如Integer的parseInt方法,写作Integer::parseInt)
(2)指向任意类型实例方法的引用(例如String的Length方法,写作String::length)
(3)指向现有对象的实例方法的引用(例如你有一个局部变量expensiveTransaction,他支持实例方法getValue,写作expensiveTransaction::getValue)
(args) -> ClassName.staticMethod(args) ClassName::staticMethod
(arg0,rest) -> arg0.instanceMethod(rest) ClassName::instanceMethod //arg0是ClassName类型的
(args) -> expr.instanceMethod(args) expr::instanceMethod
复合Lambda表达式
3.1比较器复合
苹果从小到大排列的的方法如下
inventory.sort(comparing(Apple::getWeight)); //重量正排
逆序:reversed
inventory.sort(comparing(Apple::getWeight).reversed()); //重量倒排
比较器链: thenComparing
inventory.sort(comparing(Apple::getWeight)
.reversed() //重量倒排
.thenComparing(Apple::getCountry)); //按国家排序
3.2谓词复合
negate(非) and(和) or(或)
Predicate<Apple> predicate = redApple.negate()
.and(a -> a.getWeight()>150)
.or(a -> "green".equals(a.getColor()));
3.3函数复合
andThen:会返回一个函数,它先对输入应用一个给定函数,再对输出应用另一个函数。
compose:先把给定的函数用作compose的参数里面给的那个函数,然后再把函数用于本身。
Function<Integer,Integer> f = x -> x+1;
Function<Integer,Integer> g = x -> x*2;
Function<Integer,Integer> h = f.andThen(g);
Function<Integer,Integer> k = f.compose(g);
int resultA = h.apply(1); //结果返回4
int resultB = k.apply(2) //结果返回3