我这里只是简单记录一下,让自己有个印象,如果想要详细的教程,那么可以看《Java 8实战》

lambda为简洁地表示可传递的匿名函数的一种方式。

它包含三个部分,参数、箭头、主体。如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值

List<Dog> dogs = new ArrayList<>();
(a1,a2)是参数
a1.getName().compareTo(a2.getName())是主体
dogs.sort((a1, a2) -> a1.getName().compareTo(a2.getName()));

函数式接口就是只定义一个抽象方法的接口。Lambda表达式允许你直接以内联的形式为函数式接口的抽象方法提供实现, 并把整个表达式作为函数式接口的实例、

例如:

Runnable r1 = () -> System.out.println("Hello World 1")

  •  类型推断

Java编译器会从上下文(目标类型)推断出用什么函数式接口来配合Lambda表达式,这样就可以在Lambda语法中省去标注参数类型。

List<Dog> dogs = new ArrayList<>();
dogs.sort((Dog a1, Dog a2) -> a1.getName().compareTo(a2.getName()));

可以简写为
dogs.sort((a1, a2) -> a1.getName().compareTo(a2.getName()));
  • lambda使用局部变量

Lambda表达式引用的局部变量必须是最终的( final)或事实上最终的(即没有再改过)。

#这种写法正确
 int portNumber = 1337;
        Runnable r = () -> System.out.println(portNumber);

# 再重新给portNumber 赋值会报错
 int portNumber = 1337;
        Runnable r = () -> System.out.println(portNumber);
portNumber = 3434;

为什么 Lambda 表达式(匿名类) 不能访问非 final  的局部变量呢?因为实例变量存在堆中,而局部变量是在栈上分配,Lambda 表达(匿名类) 会在另一个线程中执行。如果在线程中要直接访问一个局部变量,可能线程执行时该局部变量已经被销毁了,而 final 类型的局部变量在 Lambda 表达式(匿名类) 中其实是局部变量的一个拷贝。

  •  方法引用

使用 方 法 引用时 , 目 标引用 放 在 分隔符::前 ,方法 的 名 称放在 后 面,例如Dog::getName就是引用了Dog类中定义的方法getName。

方法引用主要有三类。

  1. 指向静态方法的方法引用(例如Integer的parseInt方法,写作Integer::parseInt)。
  2. 指 向 任 意 类 型 实 例 方 法 的 方 法 引 用 ( 例 如 String 的 length 方 法 ,写 作String::length)。
  3. 指向现有对象的实例方法的方法引用(假设你有一个局部变量expensiveTransaction用于存放Transaction类型的对象,它支持实例方法getValue,那么你就可以写expensiveTransaction::getValue)

 

改造示例

例如需要将Dog列表,根据姓名排序,那么一开始可以这么写

List<Dog> dogs = new ArrayList<>();
        dogs.sort(new Comparator<Dog>() {
            @Override
            public int compare(Dog o1, Dog o2) {
                return o1.getName().compareTo(o2.getName());
            }
        });
  • 使用lambda表达式
dogs.sort((Dog o1, Dog o2) -> o1.getName().compareTo(o2.getName()));

去掉类型判断后,变为

dogs.sort((o1, o2) -> o1.getName().compareTo(o2.getName()));

Comparator具有一个叫作comparing的静态辅助方法,所以还可以继续简写

dogs.sort(Comparator.comparing((a) -> a.getName()));
  • 加入方法引用
dogs.sort(Comparator.comparing(Dog::getName));