類型 | 接口 | 參數 | 傳回值 | 描述 |
---|---|---|---|---|
供給型接口 | Supplier<T> | None | T | 沒有輸入,傳回一個對象T |
功能型函數式接口 | Function<T, R> | T | R | 對象轉換,T->R |
消費型接口 | Consumer<T> | T | void | 改變對象T内部屬性的值 |
斷言型接口 | Predicate<T> | T | boolean | 進行邏輯判斷,傳回boolean值 |
函數式接口特點
1、三種方法
- 唯一的抽象方法
- 使用default定義普通方法(預設方法),通過對象調用。
- 使用static定義靜态方法,通過接口名調用。
2、一個新注解@FunctionInterface
如果某一個接口就是為了函數式接口而生的,使用注解@FunctionalInterface告訴編譯器這是一個函數式接口,明确這個函數中隻有一個抽象方法,當你嘗試在接口中編寫多個抽象方法的時候編譯器将不允許,但是可以有多個非抽象方法。
不過Object類的方法可以定義為抽象方法,因為接口的實作類一定是Object的子類。
二、Supplier供給型接口
Supplier無入參,有傳回結果T
@FunctionalInterface
public interface Supplier<T> {
//傳回T
T get();
}
Supplier執行個體:
Supplier<String> supplier = ()-> "Hello World!";
Supplier<String> supplier = ()-> new User();
二、Function功能型函數式接口
Function接口 接受一個輸入參數T,傳回一個結果R。
@FunctionalInterface
public interface Function<T, R> {
// 接受輸入參數,傳回一個結果。
R apply(T t);
// 傳回一個 先執行before函數對象apply方法,再執行目前函數對象apply方法的 函數對象。
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
// 傳回一個 先執行目前函數對象apply方法, 再執行after函數對象apply方法的 函數對象。
// 和compose相反
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
// 傳回一個執行了apply()方法之後隻會傳回輸入參數的函數對象。
static <T> Function<T, T> identity() {
return t -> t;
}
}
Function執行個體:
public static Integer composeTest(int value, Function<Integer, Integer> function1, Function<Integer, Integer> function2){
return function1.compose(function2).apply(value);
}
public static Integer andThenTest(int value, Function<Integer, Integer> function1, Function<Integer, Integer> function2){
return function1.andThen(function2).apply(value);
}
public static void main(String[] args) {
System.out.println(composeTest(2, val -> val * 5, val -> val + 3)); //25
System.out.println(andThenTest(2, val -> val * 5, val -> val + 3)); //13
}
三:Consumer消費型接口
一個接受單個輸入參數并且不傳回結果的操作。 與大多數其他函數接口不同, Consumer接口期望通過副作用進行操作。
@FunctionalInterface
public interface Consumer<T> {
//對給定的參數執行此操作
void accept(T t);
//andThen可以實作消費兩次。消費一次後,繼續消費一次
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
Consumer執行個體:
pair-> pair.setFrist(20);
四:Predicate斷言型接口
Predicate常用于集合的過濾,得到一個新的集合
@FunctionalInterface
public interface Predicate<T> {
//進行某些邏輯判斷并傳回一個boolean值
boolean test(T t);
//and方法接收一個Predicate類型,也就是将傳入的條件和目前條件以并且的關系過濾資料。
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
//negate就是将目前條件取反
default Predicate<T> negate() {
return (t) -> !test(t);
}
//or方法同樣接收一個Predicate類型,将傳入的條件和目前的條件以或者的關系過濾資料
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
Predicate執行個體:
public static List<Integer> andTest(List<Integer> list, Predicate<Integer> p1, Predicate<Integer> p2) {
return list.stream().filter(p1.and(p2)).collect(Collectors.toList());
}
public static List<Integer> orTest(List<Integer> list, Predicate<Integer> p1, Predicate<Integer> p2) {
return list.stream().filter(p1.or(p2)).collect(Collectors.toList());
}
public static List<Integer> negateTest(List<Integer> list, Predicate<Integer> p) {
return list.stream().filter(p.negate()).collect(Collectors.toList());
}
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> result;
//大于5并且是偶數
result = andTest(list, integer -> integer > 5, integer1 -> integer1 % 2 == 0);
result.forEach(System.out::println);//6 8 10
System.out.println("-------");
//大于5或者是偶數
result = orTest(list, integer -> integer > 5, integer1 -> integer1 % 2 == 0);
result.forEach(System.out::println);//2 4 6 7 8 9 10
System.out.println("-------");
//條件取反
result = negateTest(list, integer2 -> integer2 > 5);
result.forEach(System.out::println);// 1 2 3 4 5
System.out.println("-------");
}