简介
Lambda可以理解为简洁的表示可传递的匿名函数,包括:参数列表、函数主体、返回类型、抛出的异常列表(可以不存在)。
函数式接口:定义一个抽象方法的接口(接口可以拥有默认方法:default)。
函数式接口有什么用?
Lambda可以以内联的形式为函数式接口的抽象方法提供实现。虽然内部类也可以实现,但lambda表达式更加简洁。当然内部类也存在它的优势,它可以为接口实现多个抽象方法。
1Comparator<Apple> byWeight = 2 (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
参数列表:包括a1、a2,这里参数为显式类型(Apple类);也可以没有显示类型,java编译器会根据上下文配合Lambda表达式的函数式接口。
箭头:-> 将参数列表和函数主体分开
函数主体:要完成的功能;表达式作为返回值
11、(String s)->return s; 22、(String s)->{"Hello world"}; 33、(String s)->"Hello world"
表达式1:return是一个控制流语句,需要用{}
表达式2:“Hello world”是一个表达式,不是语句,不需要花括号。
表达式3:正确
java.util.function包中的三个常用函数式接口:
1、Predicate
1@FunctionalInterfacepublic interface Predicate<T>{ 2 boolean test(T t); 3}
2、Consumer
1@FunctionalInterface 2public interface Consumer<T>{ 3 void accept(T t); 4}
3、Function
1@FunctionalInterface 2public interface Function<T, R>{ 3 R apply(T t); 4}
注意:
1、由于Lambda只能捕捉给它的局部变量一次,局部变量必须显示申明为final或事实上为final。(局部变量保存在栈)
2、Lambda的主体为语句表达式时,它可以和返回为void的函数描述符兼容。add方法实际返回boolean类型,Consumer的accept方法返回为void类型,可以兼容而不报错。
Consumer<String> l = s -> list.add(s);
方法引用:这里选用最常见的sort方法,假设提供了一个Apple类,存在weight(重量)这个属性,类型为Integer(方便使用compareTo进行说明),现在我们要求按重量排序。
两行代码的实现相同,第一行
1apples.sort((Apple a1, Apple a2)-> a1.getWeight().compareTo(a2.getWeight())); 2 3apples.sort(Comparator.comparing(Apple::getWeight));
复合lambda表达式:将多个简单的lambda复合成复杂的表达式。
1、比较器复合
// 逆序apples.sort(Comparator.comparing(Apple::getWeight).reversed());// 比较器链apples.sort(Comparator.comparing(Apple::getWeight).thenComparing(Apple::getColor()));
2、微词复合:negate(非)、and和or。
3、函数复合
1Function<Integer, Integer> f = x -> x+1; 2Function<Integer, Integer> g = x -> x*2; 3Function<Integer, Integer> h1 = f.andThen(g); //可以看作数学函数:h1 = f(g(x)) 4Function<Integer, Integer> h2 = f.compose(g); //h1 = g(f(x)) 5int result1 = h1.apply(1); //result1 = 4 6int result2 = h2.apply(1); //result2 = 3