天天看點

Java 8 函數式接口 : Supplier、Function、Consumer、Predicate           函數式接口特點

類型 接口 參數 傳回值 描述
       供給型接口   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("-------");
    }