代わりに、フィルタの収集使用してストリームを()フィルタ()

緑の多いです:

私はこのようなデータそのルックスを含むリストを持っています

game_id | user_id | status
   1         1       STARTED
   2         1       FINISHED
   1         2       STARTED
   2         2       FINISHED

私は2つのマップにこのリストを収集する(または可能な場合は、単一のマップで)

一つのマップは、のマッピングを維持する必要があります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;
        }
    }
}

それは仕事の罰金に思えます。しかし、私はアイテムのみを残すために、ステータス、Iフィルタでゲームを計算するときFINISHEDの状態。

Map<String, Long> finishedGames = games
    .stream()
    .filter(game -> game.battleStatus.equals("FINISHED"))
    .collect(Collectors.groupingBy(Game::getUserId, Collectors.counting()));

その内部に実現する方法がありますcollect使用してのブロックを代わりにはfilter

ETO:

あなたは両方の完成と未完成のゲームをカウントする必要がある場合は、その後、別のは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())));

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=189279&siteId=1