Java 使用collect()而不是filter()筛选流

Java 使用collect()而不是filter()筛选流,java,collections,java-8,hashmap,java-stream,Java,Collections,Java 8,Hashmap,Java Stream,我有一个包含如下数据的列表 game_id | user_id | status 1 1 STARTED 2 1 FINISHED 1 2 STARTED 2 2 FINISHED user_id | all_games 1 2 2 2 我想将此列表收集到两个地图中(如果可能,也可以在一个地图中) 一

我有一个包含如下数据的列表

game_id | user_id | status
   1         1       STARTED
   2         1       FINISHED
   1         2       STARTED
   2         2       FINISHED
user_id  | all_games
   1            2
   2            2
我想将此列表收集到两个地图中(如果可能,也可以在一个地图中)

一个映射应该将
用户id
映射到用户玩的游戏数量-基本上是具有
完成状态的游戏

user_id | finished_games
   1            1
   2            1
另一个地图应该存储
用户id
到所有游戏计数。看起来是这样的

game_id | user_id | status
   1         1       STARTED
   2         1       FINISHED
   1         2       STARTED
   2         2       FINISHED
user_id  | all_games
   1            2
   2            2
我这样做(我删除了
game\u id
字段,因为它实际上并不重要)


有没有办法在
收集
块内而不是使用
过滤器

如果您需要同时计算已完成和未完成的游戏,那么另一个
分组方式可以帮助您:

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

Map<String, Map<Boolean, Long>> groupedGames = 
    games.stream()
         .collect(groupingBy(Game::getUserId, 
                      groupingBy(isFinished, counting())));
我甚至会创建一个getter
getBattleStatus()
,然后用方法引用替换
game->game.battleStatus

Map<String, Map<String, Long>> groupedGames = 
    games.stream()
         .collect(groupingBy(Game::getUserId, 
                      groupingBy(Game::getBattleStatus, counting())));
Map groupedGames=
games.stream()
.collect(groupingBy)(游戏::getUserId,
分组方式(Game::getBattleStatus,counting());

您可以使用多个
分组方式来获取此信息,例如:

Map<String, Map<String, Long>> gameStatuses = games
   .stream()
   .collect(Collectors.groupingBy(Game::getUserId, 
   Collectors.groupingBy(Game::getBattleStatus, Collectors.counting())));
System.out.println(gameStatuses);
这将为您提供以下输出:

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

您可以使用嵌套的
map.get
来获取任何用户和任何状态的计数。

是否有您试图避免
过滤器的原因?
?这真的很不清楚,您不是说过您要计算完成的
和所有游戏的计数吗?您可以在Java 9中使用,但您想知道的原因超出了我的理解。@Eugene Yes。我要把他们两个都数一数。但是我把它存储在一个单独的映射中。所以你想用一个
操作来实现吗?你的代码看起来很好,但这在我看来并不坏,因为OP说我想把这个列表收集成两张地图;如果我们不从字面上理解,我想这看起来不错。1+@Eugene哦!我不知道可以分组到同一个映射中,因为我没有考虑类“真/假”键
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}}