JDK 12 будет иметь Collectors.teeing
( webrev и CSR ), который собирает в два разных сборщика и затем объединяет оба частичных результата в окончательный результат.
Вы можете использовать его здесь, чтобы собрать до двух IntSummaryStatistics
как для координаты x
, так и для координаты y
:
List<IntSummaryStatistics> stats = points.stream()
.collect(Collectors.teeing(
Collectors.mapping(p -> p.x, Collectors.summarizingInt()),
Collectors.mapping(p -> p.y, Collectors.summarizingInt()),
List::of));
int minX = stats.get(0).getMin();
int maxX = stats.get(0).getMax();
int minY = stats.get(1).getMin();
int maxY = stats.get(1).getMax();
Здесь первый сборщик собирает статистику для x
, а второй для y
. Затем статистические данные для x
и y
объединяются в List
с помощью фабричного метода JDK 9 List.of
, который принимает два элемента.
Альтернативой List::of
для слияния будет:
(xStats, yStats) -> Arrays.asList(xStats, yStats)
Если на вашем компьютере не установлен JDK 12, вот упрощенная, обобщенная версия метода teeing
, которую вы можете безопасно использовать в качестве служебного метода:
public static <T, A1, A2, R1, R2, R> Collector<T, ?, R> teeing(
Collector<? super T, A1, R1> downstream1,
Collector<? super T, A2, R2> downstream2,
BiFunction<? super R1, ? super R2, R> merger) {
class Acc {
A1 acc1 = downstream1.supplier().get();
A2 acc2 = downstream2.supplier().get();
void accumulate(T t) {
downstream1.accumulator().accept(acc1, t);
downstream2.accumulator().accept(acc2, t);
}
Acc combine(Acc other) {
acc1 = downstream1.combiner().apply(acc1, other.acc1);
acc2 = downstream2.combiner().apply(acc2, other.acc2);
return this;
}
R applyMerger() {
R1 r1 = downstream1.finisher().apply(acc1);
R2 r2 = downstream2.finisher().apply(acc2);
return merger.apply(r1, r2);
}
}
return Collector.of(Acc::new, Acc::accumulate, Acc::combine, Acc::applyMerger);
}
Обратите внимание, что при создании возвращенного коллектора я не учитываю характеристики нижестоящих коллекторов.