1. p243: ```java // 标准的 lambda 表达式: (String first, String second) -> first.length() - second.length();

    // 如果可以从上下文推导参数类型,可以省略类型声明 Comparator comp = (first, second) -> first.length() - second.lenth();

    // 如果方法只有一个参数,且参数类型可以推导出来,那么可以省略小括号 String s = str -> str.toUpperCase();

    // 如果 lambda 表达式没有参数,仍要提供空括号 () -> { for (int i=100; i>0; i—) System.out.println(i); }

    // 如果有多条语句,就像通常的方法一样,用大括号,并包含 return 语句。 (String first, String second) -> { if (first.length() > second.length()) return 1; else if (first.length() < second.length()) return -1; else return 0; }

    1. 11. **p245**:**只有一个抽象方法的接口称为函数式接口**,需要这种接口的对象时,就可以提供一个 `lambda` 表达式。例如,在一个需要 `Comparator` 实例的地方:
    2. ```java
    3. Arrays.sort( words, (first, second) -> first.length() - second.length() );

    在底层,Arrays.sort 会接收实现了 Comparator<String> 的某个类的对象,在这个对象上调用 compare 方法会执行这个 lambda 表达式的代码。这些类和对象由虚拟机管理。

    1. p246:实际上在 Java 中对 lambda 表达式所能做的也只是转换为函数式接口。可以用声明为某个函数式接口的变量,来保存 lambda 表达式。

      1. Comparator<String> cmp = (first, second)
      2. -> first.length() - second.length()
    2. p246Java APIjava.util.function 包中定义了很多通用函数式接口。

      • ArrayList<T> 类有一个removeIf 方法,它的参数是一个 Predicate 接口:

        1. public interface Predicate<T>
        2. {
        3. boolean test( T t );
        4. //另外的默认方法和静态方法
        5. }
        6. //下面的语句将从一个数组列表中删除所有 null 值:
        7. list.removeIf( t -> t == null );
      • Objects.requireNonNullElseGet 方法的第二个参数是函数式接口Supplier<T>,只有第一个参数是null的时候,才调用Supplier。 ```java public interface Supplier { T get(); }

    //我们预计day很少为null,所以希望只在必要时才构造默认的LocalDate //通过使用Supplier,我们就能延迟这个计算: LocalDate hireDay = Objects.requireNonNullElseGet(day, () -> new LocalDate(1970, 1, 1) ); ```

    1. p248方法引用 指示编译器生成一个函数式接口的实例,覆盖这个接口的抽象方法来调用给定的方法。有三种情况:
      • object::instanceMethod
      • Class::instanceMethod 抽象方法定义的第一个参数会成为被调用方法的隐式参数。
      • Class::staticMethod 抽象方法的参数全都传递给静态方法。
    2. p248:只有当 lambda 表达式的体只调用一个方法而不作其它操作时,才能把 lambda 表达式重写为方法引用。像 s -> s.lenth() == 0 就不能,因为它有一个比较操作。