我有两个HashMap对象,定义如下:
HashMap<String, Integer> map1 = new HashMap<String, Integer>();
HashMap<String, Integer> map2 = new HashMap<String, Integer>();
我还有第三个HashMap对象:
HashMap<String, Integer> map3;
如何将map1和map2合并为map3?
我有两个HashMap对象,定义如下:
HashMap<String, Integer> map1 = new HashMap<String, Integer>();
HashMap<String, Integer> map2 = new HashMap<String, Integer>();
我还有第三个HashMap对象:
HashMap<String, Integer> map3;
如何将map1和map2合并为map3?
当前回答
如果最终的映射不需要可变性,可以使用Guava的ImmutableMap及其Builder和putAll方法,与Java的map接口方法相反,ImmutableMap可以被链接。
使用示例:
Map<String, Integer> mergeMyTwoMaps(Map<String, Integer> map1, Map<String, Integer> map2) {
return ImmutableMap.<String, Integer>builder()
.putAll(map1)
.putAll(map2)
.build();
}
当然,这个方法可以更通用,使用可变参数和循环从参数中putAll map等,但我想展示一个概念。
此外,ImmutableMap和它的构建器有一些限制(或者可能是功能?):
他们是空敌对(抛出NullPointerException -如果map中的任何键或值为空) 生成器不接受重复的键(如果添加了重复的键则抛出IllegalArgumentException)。
其他回答
组合两个可能共享公共键的映射的通用解决方案:
就地:
public static <K, V> void mergeInPlace(Map<K, V> map1, Map<K, V> map2,
BinaryOperator<V> combiner) {
map2.forEach((k, v) -> map1.merge(k, v, combiner::apply));
}
返回一个新地图:
public static <K, V> Map<K, V> merge(Map<K, V> map1, Map<K, V> map2,
BinaryOperator<V> combiner) {
Map<K, V> map3 = new HashMap<>(map1);
map2.forEach((k, v) -> map3.merge(k, v, combiner::apply));
return map3;
}
你可以对其他类型使用Collection.addAll(),例如List, Set等。对于Map,您可以使用putAll。
HashMap<Integer,String> hs1 = new HashMap<>();
hs1.put(1,"ram");
hs1.put(2,"sita");
hs1.put(3,"laxman");
hs1.put(4,"hanuman");
hs1.put(5,"geeta");
HashMap<Integer,String> hs2 = new HashMap<>();
hs2.put(5,"rat");
hs2.put(6,"lion");
hs2.put(7,"tiger");
hs2.put(8,"fish");
hs2.put(9,"hen");
HashMap<Integer,String> hs3 = new HashMap<>();//Map is which we add
hs3.putAll(hs1);
hs3.putAll(hs2);
System.out.println(" hs1 : " + hs1);
System.out.println(" hs2 : " + hs2);
System.out.println(" hs3 : " + hs3);
重复的项目将不会被添加(即重复的键),因为当我们将打印hs3时,我们将只获得键5的一个值,这将是最后一个添加的值,它将是rat。 **[设置不允许重复键,但值可以重复]
您可以使用- addAll方法
http://download.oracle.com/javase/6/docs/api/java/util/HashMap.html
但是总会有这样的问题,如果你的两个哈希映射有相同的键,那么它会用第二个哈希映射的键值覆盖第一个哈希映射的键值。
为了安全起见-更改键值-您可以在键上使用前缀或后缀-(第一个哈希映射使用不同的前缀/后缀,第二个哈希映射使用不同的前缀/后缀)
如果知道没有重复的键,或者希望map2中的值覆盖map1中的值以获得重复的键,那么可以只写
map3 = new HashMap<>(map1);
map3.putAll(map2);
如果需要更多地控制值的组合方式,可以使用Map。merge,在Java 8中添加,它使用用户提供的biffunction来合并重复键的值。merge操作单独的键和值,因此需要使用循环或Map.forEach。这里我们连接重复键的字符串:
map3 = new HashMap<>(map1);
for (Map.Entry<String, String> e : map2.entrySet())
map3.merge(e.getKey(), e.getValue(), String::concat);
//or instead of the above loop
map2.forEach((k, v) -> map3.merge(k, v, String::concat));
如果你知道你没有重复的键,并且想要强制它,你可以使用merge函数抛出AssertionError:
map2.forEach((k, v) ->
map3.merge(k, v, (v1, v2) ->
{throw new AssertionError("duplicate values for key: "+k);}));
从这个特定的问题后退一步,Java 8流库提供了toMap和groupingBy collector。如果在循环中重复合并映射,则可以重新构造计算以使用流,这既可以澄清代码,又可以使用并行流和并发收集器轻松实现并行。