我有两个类型为Map<String, Set<String>>
的地图,我需要根据每个地图的键进行合并。我使用的是Java 8.
我尝试了以下内容:
Map<String, Set<String>> collect = Stream.of(keyColumnValueAccumulator, keyColumnValues)
.map(Map::entrySet)
.flatMap(Collection::stream)
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue));
但是在运行时,这会产生一个“重复密钥”。错误。请有人帮忙吗?我还是Java 8和Stream API的新手
答案 0 :(得分:2)
使用the merge function决定在发生密钥冲突时该怎么做:
例如,您可以将两个集合并为一个然后返回新的合并结果: Stream.of(keyColumnValueAccumulator, keyColumnValues)
.map(Map::entrySet)
.flatMap(Collection::stream)
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(left, right) -> {left.addAll(right); return left;}));
或者您可以保留第一个并丢弃第二个:
Stream.of(keyColumnValueAccumulator, keyColumnValues)
.map(Map::entrySet)
.flatMap(Collection::stream)
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(left, right) -> left);
或倒数:
Stream.of(keyColumnValueAccumulator, keyColumnValues)
.map(Map::entrySet)
.flatMap(Collection::stream)
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(left, right) -> right);
或调用另一个函数来计算新值等等......
答案 1 :(得分:2)
您还可以使用Map::merge方法来避免重复键错误。
示例:
Map<String, Set<String>> accumulator = new HashMap<>();
firstMap.forEach((k, v) -> accumulator.merge(k, v, (prev, cur) -> {prev.addAll(cur); return prev;}));
secondMap.forEach((k, v) -> accumulator.merge(k, v, (prev, cur) -> {prev.addAll(cur); return prev;}));
在键碰撞的情况下,我们只是将两个集合累加为一个,但如果这不是所需的行为,您可以随时更改它或为remappingFunction
创建自定义函数。