Answers:
map3 = new HashMap<>();
map3.putAll(map1);
map3.putAll(map2);
Map
根据定义,a 中的键是唯一的
如果您知道没有重复的键,或者想让值map2
覆盖map1
重复键的值,则只需编写
map3 = new HashMap<>(map1);
map3.putAll(map2);
如果需要更多控制值组合的方法,可以使用Map.merge
Java 8中添加的,它使用用户提供的功能BiFunction
来合并重复键的值。 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));
如果您知道没有重复的键并想执行它,则可以使用抛出的合并功能AssertionError
:
map2.forEach((k, v) ->
map3.merge(k, v, (v1, v2) ->
{throw new AssertionError("duplicate values for key: "+k);}));
从这个特定问题退后一步,Java 8流库提供了toMap
和groupingBy
收集器。如果要在循环中重复合并地图,则可以重组计算以使用流,这样既可以澄清代码,又可以使用并行流和并发收集器实现轻松的并行性。
使用Java 8 Stream API的单行代码:
map3 = Stream.of(map1, map2).flatMap(m -> m.entrySet().stream())
.collect(Collectors.toMap(Entry::getKey, Entry::getValue))
此方法的优点包括传递合并功能的能力,该功能将处理具有相同键的值,例如:
map3 = Stream.of(map1, map2).flatMap(m -> m.entrySet().stream())
.collect(Collectors.toMap(Entry::getKey, Entry::getValue, Math::max))
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合并,以了解两个映射中都存在的值需要与映射功能结合的情况。
如果您不需要为可变性最终的地图,还有番石榴的 ImmutableMap
,其Builder
和putAll
方法这,相比于Java的Map
接口方法,可以链接。
使用示例:
Map<String, Integer> mergeMyTwoMaps(Map<String, Integer> map1, Map<String, Integer> map2) {
return ImmutableMap.<String, Integer>builder()
.putAll(map1)
.putAll(map2)
.build();
}
当然,此方法可以更通用,可以使用varargs和putAll
Maps
从参数循环到循环等等,但是我想展示一个概念。
此外,ImmutableMap
它的Builder
局限性很小(也许还有功能?):
NullPointerException
-如果map中的任何键或值都为null)IllegalArgumentException
如果添加了重复的键,则抛出该错误)。HashMap有一个putAll
方法。
http://download.oracle.com/javase/6/docs/api/java/util/HashMap.html
你可以使用Collection.addAll()对于其他类型,例如List
,Set
等等。Map
你可以使用putAll
。
组合两个可能共享公用密钥的映射的通用解决方案:
到位:
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;
}
您可以HashMap<String, List<Integer>>
用来合并两个哈希图,并避免丢失与同一键配对的元素。
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]}
很晚了,但是让我分享我遇到同样问题时的工作。
Map<String, List<String>> map1 = new HashMap<>();
map1.put("India", Arrays.asList("Virat", "Mahi", "Rohit"));
map1.put("NZ", Arrays.asList("P1","P2","P3"));
Map<String, List<String>> map2 = new HashMap<>();
map2.put("India", Arrays.asList("Virat", "Mahi", "Rohit"));
map2.put("NZ", Arrays.asList("P1","P2","P4"));
Map<String, List<String>> collect4 = Stream.of(map1, map2)
.flatMap(map -> map.entrySet().stream())
.collect(
Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(strings, strings2) -> {
List<String> newList = new ArrayList<>();
newList.addAll(strings);
newList.addAll(strings2);
return newList;
}
)
);
collect4.forEach((s, strings) -> System.out.println(s+"->"+strings));
它给出以下输出
NZ->[P1, P2, P3, P1, P2, P4]
India->[Virat, Mahi, Rohit, Virat, Mahi, Rohit]
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只会得到一个值,这是最后添加的值,并且会被分配。** [Set具有不允许重复的键,但值可以重复的属性]
方法1:将地图放入列表中,然后加入
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
}
方法2:法线贴图合并
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
}
您可以按照以下代码中的说明将putAll函数用于Map
HashMap<String, Integer> map1 = new HashMap<String, Integer>();
map1.put("a", 1);
map1.put("b", 2);
map1.put("c", 3);
HashMap<String, Integer> map2 = new HashMap<String, Integer>();
map1.put("aa", 11);
map1.put("bb", 12);
HashMap<String, Integer> map3 = new HashMap<String, Integer>();
map3.putAll(map1);
map3.putAll(map2);
map3.keySet().stream().forEach(System.out::println);
map3.values().stream().forEach(System.out::println);
您可以使用-addAll方法
http://download.oracle.com/javase/6/docs/api/java/util/HashMap.html
但是始终存在以下问题:-如果您的两个哈希图具有相同的任何键-则它将用第二个哈希图的键值覆盖第一个哈希图的键值。
为了安全起见,请更改键值-您可以在键上使用前缀或后缀-(第一个哈希图使用不同的前缀/后缀,第二个哈希图使用不同的前缀/后缀)