java流分组方式+聚合
public class Member {
private String name;
private String team;
private List<String> tasks;
...
}
输入列表,如:
member1, team1, [task1]
member2, team1, [task2]
member2, team1, [taks3]
member3, team2, [task4]
member3, team2, [task5, task6]
尝试按团队分组并将每个成员的任务聚合在一起,如何编写流?预期结果类似于Map<String, List<Member>>
:
team1: [
member1: [task1]
member2: [task2, task3]
]
team2: [
member3: [task4, task5, task6]
]
按团队分组很容易。挑战在于如何为每个不同的成员聚合任务,并将结果保持为“Map>
更新:这是我能做的最好的了,但它有两个步骤。有人能把这些合并成一个吗
public class Test {
public static void main(String[] args) {
Member m1 = new Member("member1", "team1", task("task1"));
Member m2 = new Member("member2", "team1", task("task2"));
Member m3 = new Member("member2", "team1", task("task3"));
Member m4 = new Member("member3", "team2", task("task4"));
Member m5 = new Member("member3", "team2", task("task5"));
List<Member> list = Arrays.asList(m1, m2, m3, m4, m5);
long start = System.currentTimeMillis();
Map<String, Map<String, Optional<Member>>> result = list.stream()
.collect(Collectors.groupingBy(Member::getTeam,
Collectors.groupingBy(Member::getName, Collectors.reducing(
(member1, member2) -> {
member1.getTasks().addAll(member2.getTasks());
return member1;
}
))));
Map<String, List<Member>> result2 = result.entrySet().stream()
.collect(Collectors.toMap(entry -> entry.getKey(),
entry -> entry.getValue().values().stream()
.map(e -> e.get()).collect(Collectors.toList())));
result2.entrySet().stream().forEach(System.out::println);
long end = System.currentTimeMillis();
System.out.println("Total:" + (end - start) + "ms");
}
private static List<String> task(String... tasks) {
List<String> list = new ArrayList<>();
Collections.addAll(list, tasks);
return list;
}
}
# 1 楼答案
这可以通过使用
Collectors.toMap
函数来实现在你的例子中:
# 2 楼答案
下面的收集器组合应该可以做到这一点
我相信这是一个很好的例子,说明了在技术上是可行的,但在可读性方面并不是一个好主意
使用以下输入进行测试时(添加了构造函数):
生成的地图包含:
# 3 楼答案
您的任务包括两个步骤:按团队分组,然后按成员分组,然后合并他们的任务
试试这个: