java8 Function

Function、BiFunction、BinaryOperator是java提供的函数式编程接口,适合用于多操作数的链式调用(A Func -> B Func -> C Func)。

Function

Function是一个函数式接口,其中有三个方法apply, compose, andThen

    // 输入一个类型为R的值,返回另一个值
    R apply(T t);

    //下面两个方法是Function组合调用

    // 先执行输入的Function,其结果作为参数再作为调用者的Function的参数
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    // 先执行调用者的Function,其结果作为参数再作为输入的Function的参数
    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

用法示例:

    public static void main(String[] args) {
        int res1 = compute1(1, e -> e + 1); // 结果:2
        int res2 = compute2(1, e -> e + 1, e -> e * 3); // 结果:4
        int res3 = compute3(1, e -> e + 1, e -> e * 3); // 结果:4
        System.out.println(res1 + ", " + res2 + ", " + res3);
    }

    public static int compute1(int x, Function<Integer, Integer> function) {
        return function.apply(x);
    }

    public static int compute2(int x, Function<Integer, Integer> after, Function<Integer, Integer> before) {
	// x作为before的参数,其结果再作为after的参数
        return after.compose(before).apply(x);
    }

    public static int compute3(int x, Function<Integer, Integer> after, Function<Integer, Integer> before) {
	// x作为after的参数先执行after的计算,其结果再作为before的参数
        return before.andThen(after).apply(x);
    }

BiFunction

BiFunction与Function类似,其中有方法:applyandThen,可以传递两个参数用来计算。
BiFunction之所以没有compose方法,因为apply的返回值只有一个,而BiFunction的参数有两个,没法用啊。

    // 输入两个分别为T、U类型的值,返回R类型的值
    R apply(T t, U u);

    // 先执行调用者的BiFunction,其结果作为参数再作为输入的Function的参数
    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));
    }

用法示例:

    public static void main(String[] args) {
        int res1 = compute1(1, 2, (e1, e2) -> e1 * e2); // 结果:2
        int res2 = compute2(1, 2, e -> e + 1, (e1, e2) -> e1 * e2); // 结果:3
        System.out.println(res1 + ", " + res2);
    }

    public static int compute1(int x, int y, BiFunction<Integer, Integer, Integer> function) {
        return function.apply(x, y);
    }

    public static int compute2(int x, int y,
                               Function<Integer, Integer> after,
                               BiFunction<Integer, Integer, Integer> before) {
	// x和y作为before先执行before逻辑,其结果再作为after的参数执行after逻辑
        return before.andThen(after).apply(x, y);
    }

BinaryFunction

BinaryFunction是BiFunction的子接口,其中有方法minBy、maxBy。通常用于求两个值的最小值和最大值。BinaryFunction 中 BiFunction 的两个参数类型一致。

public interface BinaryOperator<T> extends BiFunction<T,T,T> {
    // 返回两个数中的最小值
    public static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator) {
        Objects.requireNonNull(comparator);
        return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
    }

    // 返回两个数中的最大值
    public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {
        Objects.requireNonNull(comparator);
        return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
    }
}

用法示例:

    public static void main(String[] args) {
        int res1 = compute(1, 2, BinaryOperator.maxBy((e1, e2) -> e1 >= e2 ? 1 : -1)); // 结果:2
        int res2 = compute(1, 2, BinaryOperator.minBy((e1, e2) -> e1 >= e2 ? 1 : -1)); // 结果:1
        System.out.println(res1 + ", " + res2);
    }

    public static int compute(int x, int y, BinaryOperator<Integer> function) {
        return function.apply(x, y);
    }

Stream reduce

reduce就是利用了BiFunction和BinaryOperator进行结果的组装。
reduce是一个迭代累加器,接收一系列输入元素,并通过迭代某种操作组合成一个简单的结果。

// 初始值identity + 多个输入元素累加值
T reduce(T identity, BinaryOperator<T> accumulator);
// 多个输入元素累加值
Optional<T> reduce(BinaryOperator<T> accumulator);
// stream().reduce:初始值identity + 多个输入元素累加值
// parallelStream().reduce:迭代累加(并行计算(identity + 每个输入元素)的值)
<U> U reduce(U identity,
                     BiFunction<U, ? super T, U> accumulator,
                     BinaryOperator<U> combiner);

用法示例:

System.out.println(Arrays.asList(1, 2, 3, 4, 5).stream()
				.reduce(5, (x, y) -> x + y,
                (x, y) -> x + y)); // (((((5 + 1) + 2) + 3) + 4) + 5) = 20,串行相加
                
System.out.println(Arrays.asList(1, 2, 3, 4, 5).parallelStream()
				.reduce(5, (x, y) -> x + y,
                (x, y) -> x + y)); // (5 + 1) + (5 + 2) + (5 + 3) + (5 + 4) + (5 + 5) = 40,并行计算并相加

你可能感兴趣的:(java)