鉴于以下类(针对该问题进行了简化):
public static class Match {
private final String type;
private final int score;
public Match(String type, int score) {
this.type = type;
this.score = score;
}
public String getType() {
return type;
}
public int getScore() {
return score;
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个Stream<Match>包含该类的多个实例,相同的类型出现多次,但具有不同的分数:
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));
Run Code Online (Sandbox Code Playgroud)
我现在想要收集流,以便结果List<Match>只包含每种类型得分最高的实例.
以下代码正在运行,但我不确定它是否是"最佳"解决方案(除了可怕的读取和格式化):
.collect(Collectors.collectingAndThen(
Collectors.groupingBy(Match::getType, Collectors.collectingAndThen(
Collectors.toList(),
l -> l.stream().max(Comparator.comparing(Match::getScore)).get())), Map::values))
.forEach(m -> System.out.println(m.getType() + ": " + m.getScore()));
Run Code Online (Sandbox Code Playgroud)
和:
.collect(Collectors.collectingAndThen(
Collectors.groupingBy(Match::getType, Collectors.maxBy(Comparator.comparing(Match::getScore))), Map::values))
.forEach(m -> m.ifPresent(ma -> System.out.println(ma.getType() + ": " + ma.getScore())));
Run Code Online (Sandbox Code Playgroud)
输出(正确):
答:10
B:12
C:1
另外,我无法提取返回收集器的通用静态方法,以便我可以在需要的地方使用它,例如:
.collect(distinctMaxByProperty(Match::getType, Match::getScore)
任何帮助将不胜感激!
List当你可以在第一时间收集最大元素时,不要收集到a ,只是提取一个值,例如
Map<String,Match> 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)));
Run Code Online (Sandbox Code Playgroud)
但是每当你遇到Optional在上下文中提取一个必需品时groupingBy,有必要检查带有merge函数的map`是否可以给出一个更简单的结果:
Map<String,Match> 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))));
Run Code Online (Sandbox Code Playgroud)
一旦你有了,Map你可以通过产生你想要的输出
result.values().forEach(m -> System.out.println(m.getType() + ": " + m.getScore()));
Run Code Online (Sandbox Code Playgroud)
但是如果你不需要实际的Match实例,你可以做得更简单:
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));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
392 次 |
| 最近记录: |