1 回答

TA貢獻(xiàn)1789條經(jīng)驗(yàn) 獲得超10個(gè)贊
如果你有使用 Java9 的自由,我建議你使用flatMapping收集器來(lái)完成這件事。這是它的樣子。
Map<String, Double> avgWeightByBuildingName = buildings.stream()
.collect(Collectors.groupingBy(Building::getName,
Collectors.flatMapping(b -> b.getAnimals().stream(),
Collectors.averagingDouble(Animal::getWeight))));
然而,這里的 java8 解決方案與前者相比看起來(lái)有點(diǎn)冗長(zhǎng)。
Map<String, Double> avgWeightByBuildingName = buildings.stream()
.flatMap(b -> b.getAnimals().stream()
.map(a -> new AbstractMap.SimpleEntry<>(b.getName(), a.getWeight())))
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.averagingDouble(Map.Entry::getValue)));
flatMapping或者考慮按照此答案編寫您自己的收集器。這是我在查看上述答案和 JDK 9 源代碼后想出的一個(gè)這樣的實(shí)現(xiàn)。
static <T, U, A, R> Collector<T, ?, R> flatMapping(Function<? super T,
? extends Stream<? extends U>> mapper, Collector<? super U, A, R> downstream) {
BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
return Collector.of(downstream.supplier(), (r, t) -> {
try (Stream<? extends U> result = mapper.apply(t)) {
result.sequential().forEach(u -> downstreamAccumulator.accept(r, u));
}
}, downstream.combiner(), downstream.finisher(),
downstream.characteristics().toArray(new Characteristics[0]));
}
此外,如以下評(píng)論所述,這對(duì)于較新的 Java 版本有一個(gè)直接的遷移策略。
添加回答
舉報(bào)