JDK1.6和JDK1.8是主流的两个大版本,目前市场上用的最多最多的依然是JDK1.8。所以,我们有必要聊一聊Java8的一些新特性。
今天我们先来聊聊 深入理解lambda的奥秘 。

在数学中,函数是有输入量、输出量的一套计算方案。相对而言,面向对象过分强调“必须通过对象的形式来做事情”,而 函数式思想则尽量忽略面向对象的复杂语法——强调做什么,而不是以什么形式做。
面向对象编程是对数据进行抽象;而函数式编程是对行为进行抽象。
lambda表达式也可称为 闭包 ,是一个 匿名函数 ,是对匿名函数的简写形式,我们可以把 Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递),可以写出 更简洁 、 更灵活 的代码。
作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升。
lambda表达式的目标定位:预定义使用了 @ FunctionalInterface 注释的函数式接口,自带一个未实现的函数的方法,或者SAM(Single Abstract Method 单个抽象方法)类型。
例如,若一个方法接收Runnable、Comparator或者 Callable 接口,都有单个抽象方法,可以传入lambda表达式。
类似的,如果一个方法接受声明于 java.util.function 包内的接口,里面的每一个接口都标明类注解@FunctionalInterface,并且只有一个未实现的函数。例如常见的 Predicate、Function、Consumer 或 Supplier,那么可以向其传lambda表达式。
说到这里,相信大家已经比较明确lambda表达式了。接下来我们看看如何运用它吧。

先来看几个case

在编译器内部,会将lambda表达式翻译成私有方法,执行invokedynamic指令。我们可以使用javap -c -v查看字节码文件,当然也可以使用Idea的插件来查看字节码。
jclasslib plugin:

javap -c -v:(代码块较长,不想关注细节可直接跳过此模块)
- Classfile /Users/lige/IdeaProjects/javahomeProject/out/production/javahomeProject/com/ligejishu/lambda/LambdaDemo02.class
- Last modified 2022-8-7; size 2654 bytes
- MD5 checksum c76a7d3ce0088c93f0dc265b8eee28de
- Compiled from "LambdaDemo02.java"
- public class com.ligejishu.lambda.LambdaDemo02
- minor version: 0
- major version: 52
- flags: ACC_PUBLIC, ACC_SUPER
- Constant pool:
- #1 = Methodref #30.#54 // java/lang/Object."
" :()V - #2 = Class #55 // java/lang/Thread
- #3 = InvokeDynamic #0:#60 // #0:run:()Ljava/lang/Runnable;
- #4 = Methodref #2.#61 // java/lang/Thread."
" :(Ljava/lang/Runnable;)V - #5 = Methodref #2.#62 // java/lang/Thread.start:()V
- #6 = Class #63 // java/util/ArrayList
- #7 = Methodref #6.#54 // java/util/ArrayList."
" :()V - #8 = String #64 // a
- #9 = InterfaceMethodref #17.#65 // java/util/List.add:(Ljava/lang/Object;)Z
- #10 = String #66 // c
- #11 = String #67 // b
- #12 = InterfaceMethodref #17.#68 // java/util/List.stream:()Ljava/util/stream/Stream;
- #13 = InvokeDynamic #1:#72 // #1:test:(Ljava/lang/String;)Ljava/util/function/Predicate;
- #14 = InterfaceMethodref #73.#74 // java/util/stream/Stream.filter:(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;
- #15 = Methodref #75.#76 // java/util/stream/Collectors.toList:()Ljava/util/stream/Collector;
- #16 = InterfaceMethodref #73.#77 // java/util/stream/Stream.collect:(Ljava/uti