在使用Java 8 的Lambda表达式时,常常会因为不知函数接口的意思,而不能快速写出 Lamdda 表达式。
有时候会自定义函数,并且参数是一个参数接口,我们可以直接使用Java 8内置的函数接口,而不必使用自定义的函数接口。
综合这两方面考虑,我个从觉得,掌握所有的内置函数接口,还是有必要的。
基本函数接口
内置的函数接口有很多,如何快速记住呢?我们需要对这些接口进行分类。首先是基本接口,列表如下
函数接口 | 函数描述符 |
---|---|
Consumer<T> | T -> Void |
Supplier<T> | () -> T |
Function<T, R> | T -> R |
Predicate<T> | T -> boolean |
UnaryOperator<T> | T -> T |
BinaryOperator<T> | (T, T) -> T |
Consumer 就像一个消费者,它只消费一个东西(也就是一个对象),并不返回状态,也就是 () -> Void
所描述的。
Supplier 是一个对象提供器,但是它不需要参数就可以生成一个对象,也就是 () -> T
所描述的。
Function 就是数学中的函数,例如 g=f(x)
,因此它是通过一个参数生成一个值,也不是 T -> R
所描述的。
Predicate 是断言的意思,也就是用于判断一个对象,并返回布尔值,也就是 T -> boolean
所描述的。
UnaryOperator 是一元操作符的意思,例如取反操作,所以它是用一个对象返回另外一个对象,并且类型相同,也就是 T -> T
所描述的。
BinaryOperator 是二元操作符的意思,例如加法运算,所以它是用两个类型相同的对象操作,并返回另外一个同类型对象,也就是 (T, T) -> T
所描述的。
这些基本的函数接口还有一些变体,例如函数接口 Function 的函数描述符为 T -> R
,而函数接口 BiFunction
的函数描述符为 (T, T) -> R
。BiFunction
中的 Bi
是 Binary
的意思,它表示二元的意思,也就是有两个参数,所以 BiFunction
使用两个参数返回一个对象,因此就能明白它的意思吧。类似的还有 BiConsumer
, BiPredicate
, 其它依此类推。
带有基本类型的函数接口
由于 Java 泛型只能使用引用类型,而不能使用基本类型,因此如果在函数接口中涉及基本类型的操作,就需要装箱、拆箱的操作,这就会付出一定的代价。因此,Java 的函数接口,其中有一种类型,它使用了基本类型(例如int),而不是基本类型对应的引用类型(例如Integer)。
例如,IntSupplier 它提供一个 int 类型值,它并没有使用泛型,而使用了具体的类型 int,代码如下
public interface IntSupplier {
int getAsInt();
}
又例如 DoublePredicate 函数接口,它也没有使用泛型,而是使用 double 类型作为参数,用于作判断之用,代码如下
public interface DoublePredicate {
boolean test(double var1);
}
如果函数接口中带 to 这个单词,表示返回某种基本类型,例如 IntToLongFunction,它的函数描述符为 int -> long
,代码如下
public interface IntToLongFunction {
long applyAsLong(int var1);
}