我有两个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?
当前回答
下面的代码片段采用多个映射并将它们组合起来。
private static <K, V> Map<K, V> combineMaps(Map<K, V>... maps) {
if (maps == null || maps.length == 0) {
return Collections.EMPTY_MAP;
}
Map<K, V> result = new HashMap<>();
for (Map<K, V> map : maps) {
result.putAll(map);
}
return result;
}
演示示例链接。
其他回答
如果最终的映射不需要可变性,可以使用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)。
方法1:将映射放在List中,然后连接
public class Test15 {
public static void main(String[] args) {
Map<String, List<String>> map1 = new HashMap<>();
map1.put("London", Arrays.asList("A", "B", "C"));
map1.put("Wales", Arrays.asList("P1", "P2", "P3"));
Map<String, List<String>> map2 = new HashMap<>();
map2.put("Calcutta", Arrays.asList("Protijayi", "Gina", "Gini"));
map2.put("London", Arrays.asList( "P4", "P5", "P6"));
map2.put("Wales", Arrays.asList( "P111", "P5555", "P677666"));
System.out.println(map1);System.out.println(map2);
// put the maps in an ArrayList
List<Map<String, List<String>>> maplist = new ArrayList<Map<String,List<String>>>();
maplist.add(map1);
maplist.add(map2);
/*
<T,K,U> Collector<T,?,Map<K,U>> toMap(
Function<? super T,? extends K> keyMapper,
Function<? super T,? extends U> valueMapper,
BinaryOperator<U> mergeFunction)
*/
Map<String, List<String>> collect = maplist.stream()
.flatMap(ch -> ch.entrySet().stream())
.collect(
Collectors.toMap(
//keyMapper,
Entry::getKey,
//valueMapper
Entry::getValue,
// mergeFunction
(list_a,list_b) -> Stream.concat(list_a.stream(), list_b.stream()).collect(Collectors.toList())
));
System.out.println("Final Result(Map after join) => " + collect);
/*
{Wales=[P1, P2, P3], London=[A, B, C]}
{Calcutta=[Protijayi, Gina, Gini], Wales=[P111, P5555, P677666], London=[P4, P5, P6]}
Final Result(Map after join) => {Calcutta=[Protijayi, Gina, Gini], Wales=[P1, P2, P3, P111, P5555, P677666], London=[A, B, C, P4, P5, P6]}
*/
}//main
}
方法二:法线映射合并
public class Test15 {
public static void main(String[] args) {
Map<String, List<String>> map1 = new HashMap<>();
map1.put("London", Arrays.asList("A", "B", "C"));
map1.put("Wales", Arrays.asList("P1", "P2", "P3"));
Map<String, List<String>> map2 = new HashMap<>();
map2.put("Calcutta", Arrays.asList("Protijayi", "Gina", "Gini"));
map2.put("London", Arrays.asList( "P4", "P5", "P6"));
map2.put("Wales", Arrays.asList( "P111", "P5555", "P677666"));
System.out.println(map1);System.out.println(map2);
/*
<T,K,U> Collector<T,?,Map<K,U>> toMap(
Function<? super T,? extends K> keyMapper,
Function<? super T,? extends U> valueMapper,
BinaryOperator<U> mergeFunction)
*/
Map<String, List<String>> collect = Stream.of(map1,map2)
.flatMap(ch -> ch.entrySet().stream())
.collect(
Collectors.toMap(
//keyMapper,
Entry::getKey,
//valueMapper
Entry::getValue,
// mergeFunction
(list_a,list_b) -> Stream.concat(list_a.stream(), list_b.stream()).collect(Collectors.toList())
));
System.out.println("Final Result(Map after join) => " + collect);
/*
{Wales=[P1, P2, P3], London=[A, B, C]}
{Calcutta=[Protijayi, Gina, Gini], Wales=[P111, P5555, P677666], London=[P4, P5, P6]}
Final Result(Map after join) => {Calcutta=[Protijayi, Gina, Gini], Wales=[P1, P2, P3, P111, P5555, P677666], London=[A, B, C, P4, P5, P6]}
*/
}//main
}
在Python中,HashMap被称为字典,我们可以很容易地合并它们。
x = {'Roopa': 1, 'Tabu': 2}
y = {'Roopi': 3, 'Soudipta': 4}
z = {**x,**y}
print(z)
{'Roopa': 1, 'Tabu': 2, 'Roopi': 3, 'Soudipta': 4}
map3 = new HashMap<>();
map3.putAll(map1);
map3.putAll(map2);
用于合并两个映射的Java 8替代一行程序:
defaultMap.forEach((k, v) -> destMap.putIfAbsent(k, v));
方法参考也一样:
defaultMap.forEach(destMap::putIfAbsent);
或原始地图解与第三个地图的幂分量:
Map<String, Integer> map3 = new HashMap<String, Integer>(map2);
map1.forEach(map3::putIfAbsent);
下面是一个用Guava将两个映射合并为快速不可变映射的方法,它可以进行最少的中间复制操作:
ImmutableMap.Builder<String, Integer> builder = ImmutableMap.<String, Integer>builder();
builder.putAll(map1);
map2.forEach((k, v) -> {if (!map1.containsKey(k)) builder.put(k, v);});
ImmutableMap<String, Integer> map3 = builder.build();
请参见使用Java 8合并两个映射,了解需要使用映射函数组合两个映射中的值的情况。
你可以使用HashMap<String, List<Integer>>来合并两个HashMap,避免丢失与相同键配对的元素。
HashMap<String, Integer> map1 = new HashMap<>();
HashMap<String, Integer> map2 = new HashMap<>();
map1.put("key1", 1);
map1.put("key2", 2);
map1.put("key3", 3);
map2.put("key1", 4);
map2.put("key2", 5);
map2.put("key3", 6);
HashMap<String, List<Integer>> map3 = new HashMap<>();
map1.forEach((str, num) -> map3.put(str, new ArrayList<>(Arrays.asList(num))));
//checking for each key if its already in the map, and if so, you just add the integer to the list paired with this key
for (Map.Entry<String, Integer> entry : map2.entrySet()) {
Integer value = entry.getValue();
String key = entry.getKey();
if (map3.containsKey(key)) {
map3.get(key).add(value);
} else {
map3.put(key, new ArrayList<>(Arrays.asList(value)));
}
}
map3.forEach((str, list) -> System.out.println("{" + str + ": " + list + "}"));
输出:
{key1: [1, 4]}
{key2: [2, 5]}
{key3: [3, 6]}