A concise way to get the minimum and maximum values of Java 8 streams

Is there a simple way to extract the minimum and maximum values of the stream (based on some comparators)?

It seems that there are many methods to obtain the minimum and maximum values separately, or to sort the flow into temporary objects, such as:

List<T> sorted = Stream.of(...).sorted().collect(Collectors.toList());
T min = sorted.get(0);
T max = sorted.get(sorted.size() - 1);

But this is not simple. You need to allocate temporary objects I'd rather not assign a temporary object than pass it twice in the stream Is there a replacement?

Pair<T> extent = Stream.of(...).???

Solution

If this is a frequently needed feature, we'd better let collectors do it We need a stats class to keep count, min, Max and factory methods to create a statistics collector

Stats<String> stats = stringStream.collect(Stats.collector())

fooStream.collect(Stats.collector(fooComparator))

(perhaps a better convenient method is stats. Collect (stream))

I gave an example stats class –

https://gist.github.com/zhong-j-yu/ac5028573c986f7820b25ea2e74ed672

public class Stats<T>
{
    int count;

    final Comparator<? super T> comparator;
    T min;
    T max;

    public Stats(Comparator<? super T> comparator)
    {
        this.comparator = comparator;
    }

    public int count(){ return count; }

    public T min(){ return min; }
    public T max(){ return max; }

    public void accept(T val)
    {
        if(count==0)
            min = max = val;
        else if(comparator.compare(val,min)<0)
            min = val;
        else if(comparator.compare(val,max)>0)
            max = val;

        count++;
    }

    public Stats<T> combine(Stats<T> that)
    {
        if(this.count==0) return that;
        if(that.count==0) return this;

        this.count += that.count;
        if(comparator.compare(that.min,this.min)<0)
            this.min = that.min;
        if(comparator.compare(that.max,this.max)>0)
            this.max = that.max;

        return this;
    }

    public static <T> Collector<T,Stats<T>,Stats<T>> collector(Comparator<? super T> comparator)
    {
        return Collector.of(
            ()->new Stats<>(comparator),Stats::accept,Stats::combine,Collector.characteristics.UNORDERED,Collector.characteristics.IDENTITY_FINISH
        );
    }

    public static <T extends Comparable<? super T>> Collector<T,Stats<T>> collector()
    {
        return collector(Comparator.naturalOrder());
    }
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>