随着函数式编程越来越流行,我们的Java从Java 8开始也引进了函数式编程相关的API,再配合lambda表达式的支持,这样写起Java代码会变得越来越爽。Java 8函数相关的api放在java.util.function的包下面,这个包展开后,有一大堆的类,看了有些头晕,这里简单归类总结一下:

首先可以简单分为5大类:Consumer、Function、Operator、Predicate和Supplier。
每一类可以指向一种类型的函数。
Consumer:消费者?包含Consumer、IntConsumer、DoubleConsumer、BiConsumer等等。通常用来指向一种接收参数而且没有返回值的函数,比如:System.out.println等。下面的代码是用BiConsumer指向System.out.println并打印:
public static void main(String[] args) {
BiConsumer<PrintStream, Object> op4 = PrintStream::println;
op4.accept(System.out, "haha");
}
Function:包含Function、BiFunction、IntFunction、LongFunction、ToDoubleFunction等等。通常用来指向一种接收参数而且又有返回值的函数,比如:Math.abs、StringBuilder.append等等。以下代码就是用BiFunction来指向StringBuilder.append的:
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
BiFunction<StringBuilder, String, StringBuilder> op6 = StringBuilder::append;
op6.apply(sb, "hehe");
System.out.println(sb);
}
Operator:操作符?和Function非常像,区别是Operator要求操作数和返回值必须是同一类型的,比如Math.abs、String.concat等。包含BinaryOperator、IntBinaryOperator、UnaryOperator、LongUnaryOperator等。下面代码用IntUnaryOperator指向Math.abs:
public static void main(String[] args) {
IntUnaryOperator op = Math::abs;
System.out.println(op.applyAsInt(-5));
}
Predicate:谓词?这种类型通常又接收参数,又有返回值,但返回值类型必定是boolean。比如:String.startsWith、HashSet.contains等。包含Predicate、DoublePredicate、BiPredicate等。下面代码用BiPredicate指向String.startsWith:
public static void main(String[] args) {
BiPredicate<String, String> op7 = String::startsWith;
System.out.println(op7.test("seedeed", "see"));
}
Supplier:提供者?这种类型通常没有参数,但有返回值,可以应有到一些创建对象的方法,比如工厂方法、单例等。比如ThreadLocalRandom.current、Optional.empty、Collections.emptyList等等。下面代码用Supplier指向Collections.emptyList:
public static void main(String[] args) {
Supplier<List> op8 = Collections::emptyList;
System.out.println(op8.get().size());
}
说到这里,貌似没提到怎么指向一个没有参数也没有返回值的函数啊。
其实,java.util.function包里面压根没提供这个类。没关系,我们自己实现一个,非常简单:
@FunctionalInterface
interface Action {
void action();
}
定义好接口,并用@FunctionalInterface修饰这是一个函数式接口后,下面的代码用这个Action来分别指向System.gc和自己实现的一个方法——sayHello:
public static void main(String[] args) {
Action op9 = System::gc;
op9.action();
op9 = TestFunction::sayHello;
op9.action();
}
private static void sayHello() {
System.out.println("hello seedeed!");
}
可以看到,成功打印hello seedeed!了!!