Lambda表达式
可以把Lambda表达式理解为简洁地表示可传递的匿名函数的一种方式:它没有名称,但它
有参数列表、函数主体、返回类型。
先前:
Comparator<Apple> byWeight = new Comparator<Apple>() {
public int compare(Apple a1, Apple a2){
return a1.getWeight().compareTo(a2.getWeight());
}
};
之后(用了Lambda表达式):
Comparator<Apple> byWeight =
(Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
Lambda表达式有三个部分。
参数列表——如Comparator中compare方法的参数,两个Apple。
箭头——箭头->把参数列表与Lambda主体分隔开。
Lambda主体——比较两个Apple的重量。表达式就是Lambda的返回值了
函数式接口
可以在函数式接口上使用Lambda表达式。函数式接口就是只定义一个抽象方法的接口。比如Comparator和Runnable。
JDK中的函数式接口
Predicate ( 断言)
java.util.function.Predicate<T>
接口定义了一个名叫test的抽象方法,它接受泛型
T对象,并返回一个boolean。这恰恰和你先前创建的一样,现在就可以直接使用了。
Consumer(消费者)
java.util.function.Consumer<T>
定义了一个名叫accept的抽象方法,它接受泛型T
的对象,没有返回(void)。你如果需要访问类型T的对象,并对其执行某些操作,就可以使用
这个接口。比如,你可以用它来创建一个forEach方法,接受一个Integers的列表,并对其中
每个元素执行操作。
Function(函数-转换)
java.util.function.Function<T, R>
接口定义了一个叫作apply的方法,它接受一个
泛型T的对象,并返回一个泛型R的对象。如果你需要定义一个Lambda,将输入对象的信息映射
到输出,就可以使用这个接口(比如提取苹果的重量,或把字符串映射为它的长度)。在下面的
代码中,我们向你展示如何利用它来创建一个map方法,以将一个String列表映射到包含每个
String长度的Integer列表。
Supplier(提供者)
java.util.function.Supplier<T>
,定义了一个叫作get的方法,它没有参数,返回泛型T对象。
其他
函数式接口 | 函数描述符 | 原始类型特化 |
---|---|---|
Predicate<T> |
T->boolean | IntPredicate,LongPredicate, DoublePredicate |
Consumer<T> |
T->void | IntConsumer,LongConsumer, DoubleConsumer |
Function<T,R> |
T->R |
IntFunction<R>,IntToDoubleFunction,IntToLongFunction,LongFunction<R>,LongToDoubleFunction, LongToIntFunction,DoubleFunction<R>,ToIntFunction<T>,ToDoubleFunction<T>,ToLongFunction<T>
|
Supplier<T> |
()->T | BooleanSupplier,IntSupplier, LongSupplier,DoubleSupplier |
UnaryOperator<T> |
T->T | IntUnaryOperator, LongUnaryOperator, DoubleUnaryOperator |
BinaryOperator<T> |
(T,T)->T | IntBinaryOperator, LongBinaryOperator, DoubleBinaryOperator |
BiPredicate<L,R> |
(L,R)->boolean | |
BiConsumer<T,U> |
(T,U)->void | ObjIntConsumer<T>, ObjLongConsumer<T>, ObjDoubleConsumer<T> |
BiFunction<T,U,R> |
(T,U)->R | ToIntBiFunction<T,U>, ToLongBiFunction<T,U>, ToDoubleBiFunction<T,U> |