亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

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

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

慕勒3428872 2022-05-21 13:51:38
我有得分的球員。我想獲得所有使用流和過濾器共享最大積分的玩家。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());這可以用單個謂詞/單行來完成嗎?
查看完整描述

3 回答

?
LEATH

TA貢獻1936條經驗 獲得超7個贊

您可以收集到TreeMap第一個并且只獲取最后一個條目(最大值所在的位置)


players.stream()

       .collect(Collectors.groupingBy(

           Player::getPoints,

           TreeMap::new,

           Collectors.toList()

       ))

       .lastEntry()

       .getValue();


查看完整回答
反對 回復 2022-05-21
?
蕭十郎

TA貢獻1815條經驗 獲得超13個贊

首先按點分組,得到一個 Map 結果,然后找到 map 中的 max key。時間成本將為 O(n):


List<Player> players = new ArrayList<>();

players.stream().collect(Collectors.groupingBy(Player::getPoints))

        .entrySet().stream()

        .max(Map.Entry.comparingByKey())

        .ifPresent(System.out::println);


查看完整回答
反對 回復 2022-05-21
?
汪汪一只貓

TA貢獻1898條經驗 獲得超8個贊

這是一個使用自定義收集器的版本。它巨大、丑陋和復雜,但它在O(n)中運行,只對數據進行一次傳遞,并且幾乎不需要額外的空間。


List<Player> highest = players.stream().collect(ArrayList::new, 

    (list, player) -> {

        if (list.isEmpty() || list.get(0).getPoints() == player.getPoints()) {

            list.add(player);

        } else if (list.get(0).getPoints() < player.getPoints()) {

            list.clear();

            list.add(player);

        }

    },

    (l1, l2) -> {

        if (l1.isEmpty()) {

            l1.addAll(l2);

        } else if (!l2.isEmpty()) {

            int cmp = Integer.compare(l1.get(0).getPoints(), l2.get(0).getPoints());

            if (cmp < 0) {

                l1.clear();

                l1.addAll(l2);

            } else if (cmp == 0) {

                l1.addAll(l2);

            }

        }

    });

累加器和組合器具有關聯性的證明留給讀者作為練習。


編輯:我試圖寫一個更漂亮的組合器。我設法寫了一個更短更奇怪的。我相信它與上面的相同:


(l1, l2) -> {

    int cmp = l1.stream().findAny().flatMap(p1 -> l2.stream().findAny().map(

            p2 -> Integer.compare(p1.getPoints(), p2.getPoints()))).orElse(0);

    if (cmp < 0) l1.clear();

    if (cmp <= 0) l1.addAll(l2);

}


查看完整回答
反對 回復 2022-05-21
  • 3 回答
  • 0 關注
  • 158 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號