java8新特性-引用流-max,min

例子:

  List<User> users = new ArrayList<>();
    users.add(new User("张三",30));
    users.add(new User("李四",34));
    users.add(new User("王五",20));

   
    Optional<User> max = users.stream().max(Comparator.comparing(User::getAge));
    System.out.println(max.get());

上面的例子求出最大年龄的User。

Stream的执行流程参考https://www.cnblogs.com/shigongp/p/17181380.html。下面只说max,min的处理逻辑。

源码分析

Comparator#comparing

    public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
        Function<? super T, ? extends U> keyExtractor)
{
    Objects.requireNonNull(keyExtractor);
    return (Comparator<T> & Serializable)
        (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}

按照传入的Function结果比较,上面的例子按照User::getAge比较。

ReferencePipeline#max(Comparator<? super P_OUT> comparator)

 @Override
public final Optional<P_OUT> max(Comparator<? super P_OUT> comparator) {
    return reduce(BinaryOperator.maxBy(comparator));
}

BinaryOperator#maxBy

 public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {
    Objects.requireNonNull(comparator);
    return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
}

BinaryOperator#maxBy返回两个比较器中大的结果。

ReferencePipeline#reduce

  public final Optional<P_OUT> reduce(BinaryOperator<P_OUT> accumulator) {
    return evaluate(ReduceOps.makeRef(accumulator));
}

evaluate的执行参考https://www.cnblogs.com/shigongp/p/17181380.html。

ReduceOps#makeRef

public static <T> TerminalOp<T, Optional<T>>
makeRef(BinaryOperator<T> operator) {
    Objects.requireNonNull(operator);
    class ReducingSink
            implements AccumulatingSink<T, Optional<T>, ReducingSink> {
        private boolean empty;
        private T state;

        public void begin(long size) {
            empty = true;
            state = null;
        }

        @Override
        public void accept(T t) {
            if (empty) {
                empty = false;
                state = t;
            } else {
                state = operator.apply(state, t);
            }
        }

        @Override
        public Optional<T> get() {
            return empty ? Optional.empty() : Optional.of(state);
        }

        @Override
        public void combine(ReducingSink other) {
            if (!other.empty)
                accept(other.state);
        }
    }
    return new ReduceOp<T, Optional<T>, ReducingSink>(StreamShape.REFERENCE) {
        @Override
        public ReducingSink makeSink() {
            return new ReducingSink();
        }
    };
}

关注ReducingSink。

ReducingSink#begin

  public void begin(long size) {
            empty = true;
            state = null;
        }

设置empty为true,表示没有值,state为null,将值设为null。

ReducingSink#accept

  public void accept(T t) {
            if (empty) {
                empty = false;
                state = t;
            } else {
                state = operator.apply(state, t);
            }
        }

当执行数据处理调用Sink的accept时,调用ReducingSink#accept,按照处理数据的分割器,依次遍历元素,第一次进入此方法,empty为true,将empty设置为false,state设置为初始值,以后每次调用将值传入与state比较,operator是BinaryOperator.maxBy时表示取最大值,operator是BinaryOperator.minBy时取最小值。调用ReducingSink#get获取结果。

posted @ 2023-03-12 15:29  shigp1  阅读(258)  评论(0编辑  收藏  举报