什么是Lambda
Lambda 表达式是 JDK8 的一个新特性,可以取代大部分的匿名内部类,写出更优雅的Java代码,尤其在集合的遍历和其他集合操作中,可以极大地优化代码结构。
Lambda 表达式描述了一个代码块(或者叫匿名方法),可以将其作为参数传递给构造方法或者普通方法以便后续执行
函数式接口
@FunctionalInterface修饰 的接口,有且只有一个抽象方法
语法
参数列表 -> 代码主体
-
表达式-风格
(parameters) -> expression -
块-风格
(parameters) -> { statements; }
常用函数式接口
随Lambda一同增加的还有一个java.util.function包,其中定义了一些常见的函数式接口的。比如:
Function,接受一个输入参数,返回一个结果。参数与返回值的类型可以不同,我们之前的map方法内的lambda就是表示这个函数式接口的;Consumer,接受一个输入参数并且无返回的操作。比如我们针对数据流的每一个元素进行打印,就可以用基于Consumer的lambda;Supplier,无需输入参数,只返回结果。看接口名就知道是发挥了对象工厂的作用;Predicate,接受一个输入参数,返回一个布尔值结果。比如我们在对数据流中的元素进行筛选的时候,就可以用基于Predicate的Lambda;
方法引用
当在Lambda表达式中直接调用了一个方法时可以使用,其写法为目标引用::方法名称
-
指向静态方法的方法引用
Function<String, Integer> fun = s -> Integer.parseInt(s); Function<String, Integer> fun = Integer::parseInt; -
指向任意类型实例方法的方法引用
Function<String, Integer> fun = s -> s.length(); Function<String, Integer> fun = String::length; -
指向现存外部对象实例方法的方法引用
String s = "hello"; Supplier<Integer> len = () -> s.length(); Supplier<Integer> len = s::length;
实现原理
lambda实质是对象引用
表明上看是一个实现了接口的匿名类
1.生成一个私有的静态函数,函数中执行表达式里的内容
2.javap -v 生成字节码,看到底层使用了invokedynamic指令,动态调用对应上面的静态方法
常见的方法调用字节码
Stream原理
基本原理
Stream流计算分为三步,第一步生成流,即入口;
第二步对流中的数据进行操作,也就是中间操作
第三步返回数据,也就是结束操作。每个流至少有一个入口和一个结束操作,可以有零个或多个中间操作。需要说明的是第二步中的中间操作不是实时进行,是滞后的,等遇到结束操作的时候会执行
因此stream是惰性的,所有中间操作都是由结束操作触发的。
操作
Stream中的操作可以分为两大类:中间操作与结束操作,中间操作只是对操作进行了记录,只有结束操作才会触发实际的计算(即惰性求值),这也是Stream在迭代大集合时高效的原因之一。 中间操作又可以分为无状态(Stateless)操作与有状态(Stateful)操作,前者是指元素的处理不受之前元素的影响;后者是指该操作只有拿到所有元素之后才能继续下去。 结束操作又可以分为短路与非短路操作,这个应该很好理解,前者是指遇到某些符合条件的元素就可以得到最终结果;而后者是指必须处理所有元素才能得到最终结果。
Stream操作分类
| Stream操作分类 | 状态 | 方法 |
|---|---|---|
| 中间操作(Intermediate operations) | 无状态(Stateless) | unordered() filter() map() mapToInt() mapToLong() mapToDouble() flatMap() flatMapToInt() flatMapToLong() flatMapToDouble() peek() |
| 中间操作(Intermediate operations) | 有状态(Stateful) | distinct() sorted() sorted() limit() skip() |
| 结束操作(Terminal operations) | 非短路操作 | forEach() forEachOrdered() toArray() reduce() collect() max() min() count() |
| 结束操作(Terminal operations) | 短路操作(short-circuiting) | anyMatch() allMatch() noneMatch() findFirst() findAny() |
AbstractPipeline
AbstractPipeline中定义了三个AbstractPipeline类型的变量:sourceStage(源阶段),previousStage(上游pipeline,前一阶段),nextStage(下一阶段)。