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