java · 2022年3月8日 2

JDK8中新增的函数式接口

函数式接口是有且只有一个抽象方法的接口,并且可以有多个非抽象方法。函数式接口可以被隐式的转换成lambda表达式,所以就可以使用lambda表达式来实现一个函数式接口。

在jdk8中 java.util.function 包中,新增了很多类用来支持Java的函数式接口。

Supplier接口

Supplier接口中有一个无参有返回值的方法T get(),通过泛型来指定返回值的类型。并且lambda表达式必须返回一个与之对应的类型的数据

@FunctionalInterface
public interface Supplier<T> {
    T get();
}

实例:使用Supplier接口来计算一个数组的和

public class Demo02Interface {

    public static void main(String[] args) {
        String re = Demo02Interface.getSum(() -> {
            int result = 0;
            int[] arr = {1, 2, 3, 4};
            for (int i : arr) {
                result += i;
            }
            return result;
        });
        System.out.println(re);
    }

    public static String getSum(Supplier<Integer> supplier){
        Integer integer = supplier.get();
        return "计算结果为:" + integer;
    }
}

Consumer接口

顾名思义,Comsumer用来消费数据,Supplier用于生产数据。

void accept(T t):accept为Consumer接口中的抽象方法,用于处理所接受的参数,并且无返回值。

default Consumer<T> andThen(Consumer<? super T> after):该方法用于组合调用,如果对于某个数据需要多次调用accept来处理,则可以使用 andThen 来实现连续调用处理。

@FunctionalInterface
public interface Consumer<T> {

    void accept(T t);

    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

实例1:将字符串转为大写

public class Demo02Interface {

    public static void main(String[] args) {
        Demo02Interface.switchStr(str -> {
            System.out.println("大写:" + str.toUpperCase());
        });
    }

    public static void switchStr(Consumer<String> c){
        String str = "hello word";
        c.accept(str);
    }
}

实例2:将字符串先转大写再转小写,对于同一数据进行连续的处理可以使用andThen()来进行调用

public class Demo02Interface {

    public static void main(String[] args) {
        Demo02Interface.switchStr(str -> {
            System.out.println("大写:" + str.toUpperCase());
        }, str -> {
            System.out.println("小写:" + str.toLowerCase());
        });
    }


    public static void switchStr(Consumer<String> c, Consumer<String> c2){
        String str = "hello word";
        c.andThen(c2).accept(str);
    }
}

Function接口

Function接口有两个泛型参数,前者称为前置条件,后者称为后置条件。

R apply(T t):将前置条件转化为后置条件。

default <V> Function<V, R> compose(Function<? super V, ? extends T> before):与andThen()作用相同,但效果相反,首先执行 before。

default <V> Function<T, V> andThen(Function<? super R, ? extends V> after):组合调用

static <T> Function<T, T> identity():总是返回自己输入的参数

@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;
    }
}

实例:将String转换成int

public class Demo02Interface {

    public static void main(String[] args) {
        Demo02Interface.functionTest( str -> Integer.parseInt(str));
    }


    public static void functionTest(Function<String, Integer> string2Integer){
        int a = string2Integer.apply("121");
        System.out.println(a + 1);
    }
}

Predicate接口

Predicate用于对某种数据类型进行判断,并返回 boolean

boolean test(T t):对指定的参数进行判断,并返回一个布尔值

default Predicate<T> and(Predicate<? super T> other):表示逻辑与,将两个Predicate的结果进行与操作

default Predicate<T> or(Predicate<? super T> other):表示逻辑或,将两个Predicate的结果进行或操作

default Predicate<T> negate():表示逻辑非,将结果进行非操作

static <T> Predicate<T> isEqual(Object targetRef):比较两个对象是否相等

@FunctionalInterface
public interface Predicate<T> {

    boolean test(T t);

    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

    default Predicate<T> negate() {
        return (t) -> !test(t);
    }

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

实例1:比较两个数是否相等


public class Demo02Interface {

    public static void main(String[] args) {
        predicateTest( arg -> return 15 > arg, 12);
    }

    public static void predicateTest(Predicate<Integer> predicate, int arg){
        boolean result = predicate.test(arg);
        System.out.println(result);
    }
}

实例2:将两个比较后的结果进行与操作

public class Demo02Interface {

    public static void main(String[] args) {
        predicateTestAnd( arg -> 10 > arg,
                arg -> 15 > arg,
                12);
    }

    public static void predicateTestAnd(Predicate<Integer> predicate1, Predicate<Integer> predicate2, int arg){
        boolean result = predicate1.and(predicate2).test(arg);
        System.out.println(result);
    }
}

实例3:将两个比较后的结果进行或操作

public class Demo02Interface {

    public static void main(String[] args) {
        predicateTestOr( arg -> 10 > arg,
                arg -> 15 > arg,
                12);
    }

    public static void predicateTestOr(Predicate<Integer> predicate1, Predicate<Integer> predicate2, int arg){
        boolean result = predicate1.or(predicate2).test(arg);
        System.out.println(result);
    }
}

实例4:对结果进行取反

public class Demo02Interface {

    public static void main(String[] args) {
        predicateNegate( arg -> 12 < 10 );
    }

    public static void predicateNegate(Predicate<Integer> predicate){
        boolean test = predicate.negate().test(12);
        System.out.println(test);
    }
}

实例5:将两个对象进行equal

public class Demo02Interface {

    public static void main(String[] args) {
        predicateEqual();
    }

    public static void predicateEqual(){
        boolean test = Predicate.isEqual("test").test("te3232");
        System.out.println(test);
    }
}