一、什么是函数式接口
-
只包含一个抽象方法的接口,称为函数式接口。
-
你可以通过 Lambda 表达式来创建该接口的对象。(若 Lambda表达式抛出一个受检异常,那么该异常需要在目标接口的抽象方法上进行声明)。
-
我们可以在任意函数式接口上使用 @FunctionalInterface 注解,
这样做可以检查它是否是一个函数式接口,同时 javadoc 也会包 含一条声明,说明这个接口是一个函数式接口引入函数式接口的目的就是为了能够把lambda表达式(方法)在各个方法之间进行传递。
二、Java8之前已有的函数式接口
- java.lang.Runnable
- java.util.concurrent.Callable
- java.security.PrivilegedAction
- java.util.Comparator
- java.io.FileFilter
- java.nio.file.PathMatcher
- java.lang.reflect.InvocationHandler
- java.beans.PropertyChangeListener
- java.awt.event.ActionListener
- javax.swing.event.ChangeListener
三、Java8提供的函数式接口
Java8在java.util.function包里面提供了很多的函数式接口,主要如下:
函数式接口 | 函数描述符 | 原始类型特化 |
---|---|---|
Predicate (检测接口 | T -> boolean | IntPredicate LongPredicate DoublePredicate |
Consumer<T> (消费者接口) | T -> void | IntConsumer LongConsumer DoubleConsumer |
Supplier<T> ( 生产者接口) | () -> T | BooleanSupplier IntSupplier LongSupplier DoubleSupplier |
Function<T,R> (转换接口) | T -> R | IntFunction<R> IntToDoubleFunction IntToLongFunction LongFunction<R> LongToDoubleFunction LongToIntFunction DoubleFunction<R> ToIntFunction<T> ToDoubleFunction<T> ToLongFunction<T> |
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> |
其实可以看到,jdk8所提供的函数式接口均派生自下面几个接口(注意,这里的派生并非继承,只是表达了一种关联):
Consumer<T>
:代表了接受一个输入参数并且无返回的操作,也就是我们所说的消费者Supplier<T>
:无参数,返回一个结果,也就是我们说的生产者Predicate<T>
:接受一个输入参数,返回一个布尔值结果,多半用来检测;Function<T,R>
:接受一个输入参数,返回一个结果,可以充当转换函数。
四、自定义函数式接口
基本上,java8提供的接口已经足够我们使用了,但是在特殊情况下,需要自己定义,如下示例:
- 定义函数式接口
注意的是,这里的泛型不是必须的;@FunctionalInterface public interface SelfDefine<T, U> { T handleValue(U u); }
- 使用接口
public String handlerString(String s, SelfDefine<String, String> myFunc) { return myFunc.handleValue(s); }
- 测试代码如下
@Test public void testSelfDefine() { String s = handlerString("hello ,Google", x -> x.toUpperCase()); System.out.println(s); String s2 = handlerString("hello ,Google", x -> x.toLowerCase()); System.out.println(s2); }