源碼(删除了源碼注釋):
package java.util.function;
import java.util.Objects;
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
标注為 @FunctionalInterface 的接口被稱為函數式接口,該接口隻能有一個抽象方法。如果一個接口隻有一個抽象方法,則編譯器會認為這就是一個函數式接口。是否是一個函數式接口,需要注意的有以下幾點:
- 該注解隻能标記在”有且僅有一個抽象方法”的接口上。
- JDK8 接口中的靜态方法和預設方法,都不是抽象方法。
- 接口預設繼承 java.lang.Object,是以如果接口顯示聲明覆寫了 Object 中的方法,那麼也不算抽象方法。
-
該注解不是必須的,如果一個接口符合”函數式接口”定義,那麼加不加該注解都沒有影響。加上該注解能夠更好地讓編譯器進行檢查。如果編寫的不是函數式接口(比如有多個抽象方法),但是加上了@FunctionInterface,那麼編譯器會報錯。
報錯如下圖:
報錯代碼如下:
package test;
import java.util.function.Function;
@FunctionalInterface
public interface myFunction extends Function<String , Integer> {
Integer testFunctionalInterface();
}
因為 myFunction 接口繼承了 Function 接口,Function 接口裡面本來就定義了一個 apply() 抽象方法,因為 myFunction 接口又定義了一個抽象方法,是以不符合”函數式接口”定義了,加上 @FunctionalInterface,就會報錯。
使用 Function 接口:
- 使用 lambda 表達式直接指派
Function<String , Integer> get_length = (String s) -> {
return s.length();
};
Function<String , String> append = (String s) -> s.concat(" kaven!");
- 匿名類實作
Function<Integer , Integer> add = new Function<Integer, Integer>() {
@Override
public Integer apply(Integer integer) {
return integer+100;
}
};
生成的 class 代碼如下圖:

我覺得兩種方式都是給 Function 接口的 apply() 抽象方法進行定義。
測試代碼如下:
package test;
import java.util.function.Function;
public class testFunction {
public static void main(String[] args){
Function<String , Integer> get_length = (String s) -> {
return s.length();
};
Function<String , String> append = (String s) -> s.concat(" kaven!");
System.out.println(append.apply("Welcome"));
System.out.println(get_length.compose(append).apply("Welcome"));
System.out.println(append.andThen(get_length).apply("Welcome"));
Function<Integer , Integer> add = new Function<Integer, Integer>() {
@Override
public Integer apply(Integer integer) {
return integer+100;
}
};
System.out.println(add.apply(100));
System.out.println(Function.identity().apply("Kaven"));
}
}
輸出資料如下:
Welcome kaven!
14
14
200
Kaven
System.out.println(get_length.compose(append).apply("Welcome"));
System.out.println(append.andThen(get_length).apply("Welcome"));
這兩行代碼的效果是一樣的,先調用 append 的 apply() 方法,後調用get_length 的 apply() 方法。
源碼也可以看出來:
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));//先調用 before 的 apply() 方法,後調用 this 的 apply() 方法。
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));//先調用 this 的 apply() 方法,後調用 after 的 apply() 方法。
}
static <T> Function<T, T> identity() {
return t -> t;
}
Function 接口的靜态方法,傳回一個 Function<T, T> 執行個體,并且給這個執行個體的 apply() 抽象方法指派了一個 lambda 表達式 t -> t。是以調用 apply(“Kaven”),就會輸出 Kaven。
package java.util.function;
import java.util.Objects;
@FunctionalInterface
public interface BiFunction<T, U, R> {
R apply(T t, U u);
default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t, U u) -> after.apply(apply(t, u));
}
}