Skip to content

Instantly share code, notes, and snippets.

@zhong-j-yu
Last active July 9, 2020 02:38
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save zhong-j-yu/ac5028573c986f7820b25ea2e74ed672 to your computer and use it in GitHub Desktop.
Save zhong-j-yu/ac5028573c986f7820b25ea2e74ed672 to your computer and use it in GitHub Desktop.
class Stats - used with Stream.collect() to find min and max
import java.util.Comparator;
import java.util.stream.Collector;
import java.util.stream.LongStream;
/**
* Stats of a stream of objects, including `count`, `min`, and `max`.
* Note that `min` and `max` are undefined if `count==0`.
* <p>
* This is intended to be used with `Stream.collect()`, for example
* </p>
* <pre>
* Stats&lt;String&gt; stats = stringStream.collect(Stats.collector());
*
* fooStream.collect(Stats.collector(fooComparator));
* </pre>
* <p>
* See http://stackoverflow.com/questions/41816264
* </p>
* <p>
* License: Public Domain
* </p>
*/
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>, Stats<T>> collector()
{
return collector(Comparator.naturalOrder());
}
static class Test
{
public static void main(String[] args)
{
Stats<Long> stats = LongStream.rangeClosed(-123, +1000_000_000).boxed()
.parallel()
.collect(Stats.collector());
if(stats.count>0)
System.out.printf("min=%d, max=%d %n", stats.min, stats.max);
Comparator<Long> comparator = Comparator.<Long>naturalOrder().reversed();
stats = LongStream.rangeClosed(-123, +1000_000_000).boxed()
.parallel()
.collect(Stats.collector(comparator));
if(stats.count>0)
System.out.printf("min=%d, max=%d %n", stats.min, stats.max);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment