我有一堂课叫做Person:
class Person {
private String id;
private String name;
}
现在我有两张地图
final Map<Integer, List<Person>> map1 = ImmutableMap.of(1, ImmutableList.of(
new Person("id1", "name1"),
new Person("id2", "name2")),
2, ImmutableList.of(
new Person("id3", "name3"),
new Person("id4", "name4")));
final Map<Integer, List<Person>> map2 = ImmutableMap.of(2, ImmutableList.of(
new Person("id1", "name5")));
现在,我想基于以下内容合并这些:
以上情况的结果是
1 -> Person("id1", "name5"), Person("id2", "name2")
2 -> Person("id3", "name3"), Person("id4", "name4")
我可以使用原始方式来做到这一点,但是它很大,我试图为此提供一个干净的基于Java 8流的解决方案。
任何帮助,将不胜感激。
final HashMap<Integer, List<Person>> map1 = new HashMap<Integer, List<Person>>() {{
put(1, Arrays.asList(
new Person("id1", "name1"),
new Person("id2", "name2")));
put(2, Arrays.asList(
new Person("id3", "name3"),
new Person("id4", "name4")));
}};
final HashMap<Integer, List<Person>> map2 = new HashMap<Integer, List<Person>>() {{
put(1, Arrays.asList(
new Person("id1", "name5")));
}};
final Map<Integer, List<Person>> collect = Stream.of(map1, map2).flatMap(map -> map.entrySet().stream())
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue, (v1, v2) -> {
List<Person> h = new ArrayList<>();
h.addAll(v1);
v2.forEach(x -> {
v1.forEach(y -> {
if(x.getId().equals(y.getId())) {
h.remove(y);
}
});
});
h.addAll(v2);
return h;
}
));
System.out.println(collect);
最佳答案
您可能希望在那里进行一些抽象以提高可读性:
Map<Integer, List<Person>> collect =
Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
.collect(Collectors.toMap(Map.Entry::getKey,
Map.Entry::getValue, this::mergeFunc));
public List<Person> mergeFunc(List<Person> peopleOne, List<Person> peopleTwo) {
List<Person> mergedPeople = new ArrayList<>(peopleOne);
mergedPeople.removeIf(y -> peopleTwo.stream().anyMatch(p -> y.getId().equals(p.getId())));
mergedPeople.addAll(peopleTwo);
return mergedPeople;
}