Last active
July 9, 2020 02:38
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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<String> 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