上一节里,介绍了一个函数接口:
java.util.function.Consumer除了 Consumer之外,java.util.function 中还有很多其他的函数接口,从文件名可以看出,它们大致分为以下几类:
类别 | 描述 |
Consumer | 函数接受一些输入参数,但不提供返回值 |
Predicate | 谓词。函数接受一些参数,并返回一个true/false的值 |
Supplier | 供应者。函数不需要参数,并提供一个返回值 |
Operator | 函数需要一个或多个同类型的参数,并返回一个同类型的返回值 |
Function | 函数接受一些输入参数,并提供一个返回值 |
下面是一些例子.
一、BiFunction
首先看BiFunction的Doc说明:
Represents a function that accepts two arguments and produces a result
大意就是只要一个函数需要两个参数,并有返回值,则可以使用BiFunction代表。如下:
class Calculator<T, U, R>{ public R add(BiFunction<T, U, R> bc, T t, U u){ return bc.apply(t, u); } }
这里BiFunction代表函数引用,t和u代表要传入函数的两个参数,R表示返回值类型。可以如下使用函数引用调用:
Calculator<Integer, Integer, Integer> calculator = new Calculator<>(); Integer add = calculator.add(Math::addExact, 3, 5); System.out.println(add);
也可以使用Lambda表达式:
Calculator<Integer, Integer, Integer> calculator = new Calculator<>(); Integer add = calculator.add((n, m)->{return n+m;}, 3, 5); System.out.println(add);
这里n和m分别是函数需要的两个参数,3和5分别是传入的参数,参数类型由编译器推断。
二、Predicate
看Predicate的Doc说明:
Represents a predicate (boolean-valued function) of one argument
代表一个返回boolean值的,需要一个参数的谓词。
Predicate<Integer> p = n -> {return n>0;}; boolean test = p.test(4); System.out.println(test);
这里定义了一个用来判断一个数是不是正数的谓词。
三、自定义函数接口
可以自定义函数接口。任何一个只有一个未定义的方法的接口都可以认为是一个函数接口,例如:
interface PositiveNumber<T>{ boolean test(T a); }
可以如上面Predicate一样的使用,例如:
PositiveNumber<Integer> pn = n -> {return n>0;}; boolean isPositive = pn.test(4); System.err.println(isPositive);
通常,一个接口会加上注释@FunctionalInterface,用于表明当前接口是一个函数接口。@FunctionalInterface本身不是必须的,但是加上的一个好处就是通常IDE会有错误提示,如果一个接口中有多于一个示实现的方法,例如:
@FunctionalInterface interface PositiveNumber<T>{ boolean test(T a); boolean test2(T a); }
则IDE通常会显示一个错误。