说我有以下两个地图:
Map<Member, List<Message>> one = ...;//one constructed somehow
Map<Member, List<Message>> two = ...;//two also constructed somehow
我想获得包含一个和两个内容的第三张地图。
因此,如果成员键同时位于一个和两个中,则来自两个条目的列表值将被添加到来自一个条目的列表值中。
什么是最好的和最干净的方法来实现可能使用Java 8?
最佳答案
您可以使用合并方法。
Map<Member, List<Message>> third = new HashMap<>(one);
two.forEach((k, v) -> third.merge(k, v, (v1, v2) -> {v1.addAll(v2); return v1;}));
由于您要操纵相同的参考,这也会修改地图
one
中的列表。如果您不想要,即创建一个新列表,则可以这样操作:Map<Member, List<Message>> third = new HashMap<>(one);
two.forEach((k, v) -> third.merge(k, v, (v1, v2) -> Stream.concat(v1.stream(), v2.stream()).collect(toList())));
合并后的列表将是一个新列表,但请注意,两个地图中都不存在的键不会出现这种情况。您需要深度复制所有列表以实现此目的。
刚刚使用Stream API添加了另一个解决方案:
Map<Member, List<Message>> third = Stream.of(one, two)
.flatMap(m -> m.entrySet().stream())
.collect(toMap(Map.Entry::getKey,
Map.Entry::getValue,
(l1, l2) -> Stream.concat(l1.stream(), l2.stream()).collect(toList())));
我还添加了对proton-pack library的贡献。有了这个你也可以这样实现:
Map<Member, List<Message>> third = MapStream.ofMaps(one, two)
.mergeKeys((l1, l2) -> Stream.concat(l1.stream(), l2.stream()).collect(toList()))
.collect();