java - 如何使用Java流获得具有相同最大值的所有对象?

我有得分的球员。我想获得所有使用流和过滤器共享最大积分的玩家。


public class Player {

    private int points; // Getter omitted

}

我可以通过首先获得得分最高的玩家,然后过滤所有得分相同的玩家来做到这一点。


Player topPlayer = players.stream().max(Comparator.comparing(Player::getPoints)).orElse(null);


players.stream().filter(p -> p.getPoints() == topPlayer.getPoints()).collect(Collectors.toList());

这可以用单个谓词/单行来完成吗?


慕勒3428872
浏览 134回答 3
3回答

LEATH

您可以收集到TreeMap第一个并且只获取最后一个条目(最大值所在的位置)players.stream()       .collect(Collectors.groupingBy(           Player::getPoints,           TreeMap::new,           Collectors.toList()       ))       .lastEntry()       .getValue();

萧十郎

首先按点分组,得到一个 Map 结果,然后找到 map 中的 max key。时间成本将为 O(n):List<Player> players = new ArrayList<>();players.stream().collect(Collectors.groupingBy(Player::getPoints))&nbsp; &nbsp; &nbsp; &nbsp; .entrySet().stream()&nbsp; &nbsp; &nbsp; &nbsp; .max(Map.Entry.comparingByKey())&nbsp; &nbsp; &nbsp; &nbsp; .ifPresent(System.out::println);

汪汪一只猫

这是一个使用自定义收集器的版本。它巨大、丑陋和复杂,但它在O(n)中运行,只对数据进行一次传递,并且几乎不需要额外的空间。List<Player> highest = players.stream().collect(ArrayList::new,&nbsp;&nbsp; &nbsp; (list, player) -> {&nbsp; &nbsp; &nbsp; &nbsp; if (list.isEmpty() || list.get(0).getPoints() == player.getPoints()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; list.add(player);&nbsp; &nbsp; &nbsp; &nbsp; } else if (list.get(0).getPoints() < player.getPoints()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; list.clear();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; list.add(player);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; },&nbsp; &nbsp; (l1, l2) -> {&nbsp; &nbsp; &nbsp; &nbsp; if (l1.isEmpty()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; l1.addAll(l2);&nbsp; &nbsp; &nbsp; &nbsp; } else if (!l2.isEmpty()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int cmp = Integer.compare(l1.get(0).getPoints(), l2.get(0).getPoints());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (cmp < 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; l1.clear();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; l1.addAll(l2);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else if (cmp == 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; l1.addAll(l2);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; });累加器和组合器具有关联性的证明留给读者作为练习。编辑:我试图写一个更漂亮的组合器。我设法写了一个更短更奇怪的。我相信它与上面的相同:(l1, l2) -> {&nbsp; &nbsp; int cmp = l1.stream().findAny().flatMap(p1 -> l2.stream().findAny().map(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p2 -> Integer.compare(p1.getPoints(), p2.getPoints()))).orElse(0);&nbsp; &nbsp; if (cmp < 0) l1.clear();&nbsp; &nbsp; if (cmp <= 0) l1.addAll(l2);}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java