Skip to content

Instantly share code, notes, and snippets.

@apatrida
Last active January 7, 2016 23:09
Show Gist options
  • Save apatrida/fe04727fa0db290d140f to your computer and use it in GitHub Desktop.
Save apatrida/fe04727fa0db290d140f to your computer and use it in GitHub Desktop.
Kotlin brevity as seen when comparing the implementation internally of JDK 8 Stream.collect summarizingInt and a custom Kotiln version. See many examples comparing Java 8 Stream.collect vs. Kotlin stdlib (http://stackoverflow.com/questions/34642254)
// Shown from the Java 8 JDK source code, only comments removed.
public static <T>
Collector<T, ?, IntSummaryStatistics> summarizingInt(ToIntFunction<? super T> mapper) {
return new CollectorImpl<T, IntSummaryStatistics, IntSummaryStatistics>(
IntSummaryStatistics::new,
(r, t) -> r.accept(mapper.applyAsInt(t)),
(l, r) -> { l.combine(r); return l; }, CH_ID);
public class IntSummaryStatistics implements IntConsumer {
private long count;
private long sum;
private int min = Integer.MAX_VALUE;
private int max = Integer.MIN_VALUE;
public IntSummaryStatistics() { }
@Override
public void accept(int value) {
++count;
sum += value;
min = Math.min(min, value);
max = Math.max(max, value);
}
public void combine(IntSummaryStatistics other) {
count += other.count;
sum += other.sum;
min = Math.min(min, other.min);
max = Math.max(max, other.max);
}
public final long getCount() {
return count;
}
public final long getSum() {
return sum;
}
public final int getMin() {
return min;
}
public final int getMax() {
return max;
}
public final double getAverage() {
return getCount() > 0 ? (double) getSum() / getCount() : 0.0d;
}
@Override
public String toString() {
return String.format(
"%s{count=%d, sum=%d, min=%d, average=%f, max=%d}",
this.getClass().getSimpleName(),
getCount(),
getSum(),
getMin(),
getAverage(),
getMax());
}
}
@FunctionalInterface
public interface ToIntFunction<T> {
int applyAsInt(T var1);
}
IntSummaryStatistics ageSummary =
persons.stream().collect(Collectors.summarizingInt(p -> p.age));
System.out.println(ageSummary);
// output: IntSummaryStatistics{count=4, sum=76, min=12, average=19.000000, max=23}
data class SummaryStatisticsInt(var count: Int = 0, var sum: Int = 0, var min: Int = Int.MAX_VALUE, var max: Int = Int.MIN_VALUE, var avg: Double = 0.0) {
fun accumulate(newInt: Int): SummaryStatisticsInt {
count++
sum += newInt
min = min.coerceAtMost(newInt)
max = max.coerceAtLeast(newInt)
avg = sum.toDouble() / count
return this
}
}
inline fun Collection<Int>.summarizingInt(): SummaryStatisticsInt =
this.fold(SummaryStatisticsInt()) { stats, num -> stats.accumulate(num) }
inline fun <T: Any> Collection<T>.summarizingInt(transform: (T)->Int): SummaryStatisticsInt =
this.fold(SummaryStatisticsInt()) { stats, item -> stats.accumulate(transform(item)) }
val stats1 = persons.map { it.age }.summarizingInt()
// or shorter:
val stats2 = persons.summarizingInt { it.age }
println(stats2)
// output: SummaryStatisticsInt(count=4, sum=76, min=12, max=23, avg=19.0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment