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

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

使用 collect() 而不是 filter() 過濾流

使用 collect() 而不是 filter() 過濾流

蠱毒傳說 2022-05-25 16:53:47
我的列表包含看起來像這樣的數據game_id | user_id | status   1         1       STARTED   2         1       FINISHED   1         2       STARTED   2         2       FINISHED我想將此列表收集到兩個地圖中(或者如果可能的話在單個地圖中)一張地圖應保持與user_id用戶玩過的游戲數量的映射 - 基本上是帶有finished狀態的游戲user_id | finished_games   1            1   2            1另一張地圖應存儲user_id到所有游戲計數。它看起來像這樣user_id  | all_games   1            2   2            2我這樣做(我刪除了game_id字段,因為它實際上并不重要)import java.util.*;import java.util.stream.*;public class MyClass {    public static void main(String args[]) {        List<Game> games = Arrays.asList(            create("user-1", "STARTED"),            create("user-2", "STARTED"),            create("user-1", "FINISHED"),            create("user-2", "FINISHED"),            create("user-1", "FINISHED"),            create("user-2", "FINISHED")        );        // expect user-1: all_games (3), finished_games (2)        Map<String, Long> allGames = games            .stream()            .collect(Collectors.groupingBy(Game::getUserId, Collectors.counting()));        System.out.println(allGames);        Map<String, Long> finishedGames = games            .stream()            .filter(game -> game.battleStatus.equals("FINISHED"))            .collect(Collectors.groupingBy(Game::getUserId, Collectors.counting()));        System.out.println(finishedGames);    }    private static Game create(String id, String status) {        Game game = new Game();        game.userId = id;        game.battleStatus = status;        return game;    }    private static class Game {        String userId;        String battleStatus;        public String getUserId() {            return userId;        }    }}它似乎工作正常。但是當我計算帶有狀態的游戲時,我會進行過濾以便只留下帶有FINISHED狀態的項目。Map<String, Long> finishedGames = games    .stream()    .filter(game -> game.battleStatus.equals("FINISHED"))    .collect(Collectors.groupingBy(Game::getUserId, Collectors.counting()));有沒有辦法實現內部collect塊而不是使用filter?
查看完整描述

2 回答

?
揚帆大魚

TA貢獻1799條經驗 獲得超9個贊

您可以使用多個groupingBy來獲得這個,例如:


Map<String, Map<String, Long>> gameStatuses = games

   .stream()

   .collect(Collectors.groupingBy(Game::getUserId, 

   Collectors.groupingBy(Game::getBattleStatus, Collectors.counting())));

System.out.println(gameStatuses);

為此,您需要為Game類添加一個吸氣劑battleStatus,例如:


private static class Game {

    String userId;

    String battleStatus;


    public String getUserId() {

        return userId;

    }


    public String getBattleStatus() {

        return battleStatus;

    }

}

這將為您提供以下輸出:


{user-1={STARTED=1, FINISHED=2}, user-2={STARTED=1, FINISHED=2}}

您可以使用嵌套map.get來獲取任何用戶和任何狀態的計數。


查看完整回答
反對 回復 2022-05-25
?
ibeautiful

TA貢獻1993條經驗 獲得超6個贊

如果您需要計算已完成和未完成的游戲,那么另一個groupingBy可以幫助您:


Function<Game, Boolean> isFinished = game -> "FINISHED".equals(game.battleStatus);


Map<String, Map<Boolean, Long>> groupedGames = 

    games.stream()

         .collect(groupingBy(Game::getUserId, 

                      groupingBy(isFinished, counting())));

或者您可能想自己分組battleStatus:


Map<String, Map<String, Long>> groupedGames = 

    games.stream()

         .collect(groupingBy(Game::getUserId, 

                      groupingBy(game -> game.battleStatus, counting())));

我什至會創建一個吸氣劑getBattleStatus(),然后game -> game.battleStatus用方法參考替換Game::getBattleStatus:


Map<String, Map<String, Long>> groupedGames = 

    games.stream()

         .collect(groupingBy(Game::getUserId, 

                      groupingBy(Game::getBattleStatus, counting())));


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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