Given the following class (simplified for the question):
public static class Match {
private final String type;
private fina
-
Don’t collect into a List
, just to extract one value, when you can collect the maximum element in the first place, e.g.
Map result =
Stream.of(new Match("A", 1), new Match("A", 2), new Match("A", 4), new Match("A", 10),
new Match("B", 3), new Match("B", 6), new Match("B", 12), new Match("C", 1))
.collect(Collectors.groupingBy(Match::getType, Collectors.collectingAndThen(
Collectors.reducing(BinaryOperator.maxBy(
Comparator.comparingInt(Match::getScore))),
Optional::get)));
But whenever you encounter the necessity to extract an Optional
in the context of groupingBy
, it’s worth checking whether toMap` with merge function can give a simpler result:
Map result =
Stream.of(new Match("A", 1), new Match("A", 2), new Match("A", 4), new Match("A", 10),
new Match("B", 3), new Match("B", 6), new Match("B", 12), new Match("C", 1))
.collect(Collectors.toMap(Match::getType, Function.identity(),
BinaryOperator.maxBy(Comparator.comparingInt(Match::getScore))));
Once you have the Map
you can produce your desired output via
result.values().forEach(m -> System.out.println(m.getType() + ": " + m.getScore()));
But if you don’t need the actual Match
instances, you can do it even simpler:
Stream.of(new Match("A", 1), new Match("A", 2), new Match("A", 4), new Match("A", 10),
new Match("B", 3), new Match("B", 6), new Match("B", 12), new Match("C", 1))
.collect(Collectors.toMap(Match::getType, Match::getScore, Math::max))
.forEach((type,score) -> System.out.println(type + ": " + score));
- 热议问题