天天看点

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("-------");
    }