【发布时间】:2019-06-22 09:11:23
【问题描述】:
我的列表包含如下所示的数据
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?
【问题讨论】:
-
你有什么理由试图避免
filter? -
这个真的不清楚,你不是说你自己算
FINISHED和所有游戏都算什么吗? -
你可以在 Java 9 中使用
Collectors.filtering(),但你为什么要这样做超出了我的理解。 -
@Eugene 是的。我需要数他们两个。但我将其存储在单独的地图中。
-
所以您想使用单个
stream操作来实现这一目标?顺便说一句,您的代码看起来非常好
标签: java collections java-8 hashmap java-stream