I have a class called Person :
class Person {
private String id;
private String name;
}
Now I have two maps
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")));
Now I would like to merge these based on following:
Result for the case above would be
1 -> Person("id1", "name5"), Person("id2", "name2")
2 -> Person("id3", "name3"), Person("id4", "name4")
I am able to do it using the primitive way, but its a but large, I am trying to come up with a clean java 8 stream based solution for this.
Any help would be appreciated.
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);
You might want some abstraction there possibly for better readability:
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;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.