- p243: ```java // 标准的 lambda 表达式: (String first, String second) -> first.length() - second.length();
// 如果可以从上下文推导参数类型,可以省略类型声明
Comparator
// 如果方法只有一个参数,且参数类型可以推导出来,那么可以省略小括号 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; }
11. **p245**:**只有一个抽象方法的接口称为函数式接口**,需要这种接口的对象时,就可以提供一个 `lambda` 表达式。例如,在一个需要 `Comparator` 实例的地方:
```java
Arrays.sort( words, (first, second) -> first.length() - second.length() );
在底层,Arrays.sort
会接收实现了 Comparator<String>
的某个类的对象,在这个对象上调用 compare
方法会执行这个 lambda
表达式的代码。这些类和对象由虚拟机管理。
p246:实际上在
Java
中对lambda
表达式所能做的也只是转换为函数式接口。可以用声明为某个函数式接口的变量,来保存lambda
表达式。Comparator<String> cmp = (first, second)
-> first.length() - second.length()
p246:
Java API
在java.util.function
包中定义了很多通用函数式接口。ArrayList<T>
类有一个removeIf
方法,它的参数是一个Predicate
接口:public interface Predicate<T>
{
boolean test( T t );
//另外的默认方法和静态方法
}
//下面的语句将从一个数组列表中删除所有 null 值:
list.removeIf( t -> t == null );
Objects.requireNonNullElseGet
方法的第二个参数是函数式接口Supplier<T>
,只有第一个参数是null的时候,才调用Supplier。 ```java public interface Supplier{ T get(); }
//我们预计day很少为null,所以希望只在必要时才构造默认的LocalDate
//通过使用Supplier
- p248:方法引用 指示编译器生成一个函数式接口的实例,覆盖这个接口的抽象方法来调用给定的方法。有三种情况:
object::instanceMethod
Class::instanceMethod
抽象方法定义的第一个参数会成为被调用方法的隐式参数。Class::staticMethod
抽象方法的参数全都传递给静态方法。
- p248:只有当
lambda
表达式的体只调用一个方法而不作其它操作时,才能把lambda
表达式重写为方法引用。像s -> s.lenth() == 0
就不能,因为它有一个比较操作。