【发布时间】:2016-06-05 05:19:36
【问题描述】:
我的问题基本上归结为这个简化的例子。我有从数据库返回的数据,其中行中有一些重复的信息。
在此示例中,我有一个从数据库返回的 TeamRow 对象列表。我可以使用Collectors.groupingBy 轻松地将这些分组:
public class TeamRow {
private int id;
private String name;
private String player;
public TeamRow(int id, String name, String player) {
this.id = id;
this.name = name;
this.player = player;
}
public int getId() {return id;}
public String getName() { return name; }
public String getPlayer() {return player;}
}
public class Team {
private int id;
private String name;
private List<String> players;
public Team(int id, String name, List<String> players) {
this.id = id;
this.name = name;
this.players = new ArrayList<String>(players);
}
}
List<TeamRow> dbTeams = new ArrayList<TeamRow>();
dbTeams.add(new TeamRow(1, "Team1", "Jonny"));
dbTeams.add(new TeamRow(1, "Team1", "Rob"));
dbTeams.add(new TeamRow(1, "Team1", "Carlos"));
dbTeams.add(new TeamRow(2, "Team2", "Shane"));
dbTeams.add(new TeamRow(2, "Team2", "Lucas"));
dbTeams.add(new TeamRow(3, "Team3", "Geraint"));
dbTeams.add(new TeamRow(3, "Team3", "Rocky"));
dbTeams.add(new TeamRow(3, "Team3", "Wayne"));
dbTeams.add(new TeamRow(3, "Team3", "Dwayne"));
dbTeams.add(new TeamRow(3, "Team3", "Lester"));
Map<Integer, List<TeamRow>> myMap = dbTeams.stream().collect(Collectors.groupingBy(TeamRow::getId));
但是,我实际上想要实现的是将TeamRows 转换为Teams。这样 id 和 name 只表示一次,并且玩家存储在 Team 对象的 List 中。我可以通过在地图上添加forEach 来实现这一点,如下所示。
但我一直试图弄清楚是否有一种方法可以通过添加某种映射器或下游收集器来实现相同的结果。这甚至比添加后续的forEach 有什么好处吗?例如:
List<Team> teams = dbTeams.stream().collect(Collectors.groupingBy(TeamRow::getId, ???), ???).???;
使用 forEach 进行转换:
List<Team> teams = new ArrayList<>();
myMap.forEach((id, teamRows) -> {
if (teamRows.size() > 0) {
TeamRow tr = teamRows.get(0);
List<String> players = teamRows.stream().map(TeamRow::getPlayer).collect(Collectors.toList());
teams.add(new Team(id, tr.getName(), players));
}
});
【问题讨论】:
标签: java mapping grouping java-stream collectors