一、什麼是函數式接口
-
只包含一個抽象方法的接口,稱爲函數式接口。
-
你可以通過 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); }