How to Combine Two Hashmap Objects Containing the Same Types

How can I combine two HashMap objects containing the different types?

Your keys are of the same type (String), but the values are not even related by an interface or super class, you will need to define a Map<String, Object> and make use of the Map#putAll method

Map<String, String> requestParams = new HashMap<>();
Map<String, Boolean> requestParamForOauth = new HashMap<>();
Map<String, Object> requestParamForOauth2 = new HashMap<>();
requestParamForOauth2.putAll(requestParams);
requestParamForOauth2.putAll(requestParamForOauth);

How to merge multiple Maps having the same keys but different values into a single Map

You can utilize Java 8 method merge() to combine the data of each entry:

List<Map<String, Double>> list = // initializing source list
Map<String, Double> mergedMap = new HashMap<>();

list.forEach(map -> map.forEach((k, v) -> mergedMap.merge(k, v, Double::sum)));

See that code run live at Ideone.com.

Or you can make use of Stream API with combination of built-in collectors groupingBy() and summingDouble():

Map<String, Double> mergedMap = list.stream()
.flatMap(map -> map.entrySet().stream())
.collect(Collectors.groupingBy(
Map.Entry::getKey, Collectors.summingDouble(Map.Entry::getValue)
));

Take a look at these tutorials provided by Oracle for more information on lambda expressions and streams.

merge two Map Values in Java and if key is same append the Values not overwrite in Java 7 or Java 8

You make use of the merging function provided to Collectors.toMap that specifies what to do with values of duplicate keys with Streams. Demo

final Map<String, Set<String>> map3 = Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(a, b) -> Stream.concat(a.stream(), b.stream()).collect(Collectors.toSet())));

You can apply a similar approach using Map#merge. Demo

final Map<String, Set<String>> map3 = new HashMap<>(map1);
map2.forEach((key, val) -> map3.merge(key, val,
(a, b) -> Stream.concat(a.stream(), b.stream()).collect(Collectors.toSet())));

Java combining two hashmaps of the same type into a new hashmap keeping duplicates

You almost had it with your use of a Java stream. The only thing you missed that you can provide a "merger function" that takes care of resolving collisions when the same key exists in both maps. Since it doesn't matter in our case which one we pick, I added a very simple merger that just pick one of them arbitrarily:

combinedMap = Stream.of(map1, map2)
.flatMap(m -> m.entrySet().stream())
.collect(Collectors.toMap(
Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1));

System.out.println(combinedMap);

Results:

{111=Frank, 222=Ted, 333=Roger, 555=Peter, 888=Kent}

How merge list when combine two hashMap objects in Java

In short, you can't. map3 doesn't have the correct types to merge map1 and map2 into it.

However if it was also a HashMap<String, List<Incident>>. You could use the putAll method.

map3 = new HashMap<String, List<Incident>>();
map3.putAll(map1);
map3.putAll(map2);

If you wanted to merge the lists inside the HashMap. You could instead do this.

map3 = new HashMap<String, List<Incident>>();
map3.putAll(map1);
for(String key : map2.keySet()) {
List<Incident> list2 = map2.get(key);
List<Incident> list3 = map3.get(key);
if(list3 != null) {
list3.addAll(list2);
} else {
map3.put(key,list2);
}
}

How to convert a list of two hashmaps back into a Map?

You can use the merge() function into the java.util.Map interface. This way you can also introduce the logic to apply if two elements on your maps have the same key.

Here is a junit example I made where logic applied in the case of key conflict is to concatenate element string values with pattern "value1-value2" if values are differents:

@Test
public void mapMergeTest(){
Map<String, Object> body1=Map.of("key1","value1","key2","value2","key3","value3");
System.out.println("Merged body1: \n"+body1);
Map<String, Object> body2=Map.of("key1","value1","key2","value2");
System.out.println("Merged body2: \n"+body2);

Map<String, Object> mergedBody = new HashMap<>(body1);
body2.forEach(
(key, value) -> {
mergedBody.merge(key, value, (v1, v2) -> {
if(v1.equals(v2))
return v1.toString();
return v1.toString() + "-" + v2.toString();
});
});
System.out.println("Merged body: \n"+mergedBody);
}

The output is:

Body1: 
{key1=value1, key2=value2, key3=value3}
Body2:
{key1=value5, key2=value2}
Merged body:
{key1=value1-value5, key2=value2, key3=value3}

So just change the merge key conflict logic according to your needs.

Combining two hashmaps with the same key and same or different values

This line:

Vector<String> aValues = a.get(entry.getValue());

should be:

Vector<String> aValues = entry.getValue();

UPDATE:

Oh! and same goes for bValues

UPDATE 2:

Yet another issue: entriesA.contains(aKey) should be a.contains(aKey)

UPDATE 3:

Try something like this:

    LinkedHashMap<String, Vector<String>> c = new LinkedHashMap<String, Vector<String>>();

for (Map.Entry<String, Vector<String>> entry : a.entrySet()) {
Vector<String> aValues = entry.getValue();
String aKey = entry.getKey();
c.put(aKey, new Vector<String>(aValues));
}
for (Map.Entry<String, Vector<String>> entry : b.entrySet()) {
Vector<String> bValues = entry.getValue();
String bKey = entry.getKey();
Vector<String> cValues = c.get(bKey);
if (cValues == null) {
c.put(bKey, new Vector<String>(bValues));
} else {
cValues.addAll(bValues);
}
}
return c;

UPDATE 4:

To avoid duplicate values, replace line:

        cValues.addAll(bValues);

With:

Set<String> values = new HashSet<String>(cValues);
values.addAll(bValues);
cValues.clear();
cValues.addAll(values);

This will only deal with duplicates created by the merge though, not those that already existed.

Java: Merge two hashmaps?

You can iterate through the second map and update HM1 dynamically:

HM2.entrySet()
.forEach(entry -> HM1.compute(
entry.getKey(),
(key, value) -> value == null ?
entry.getValue() :
entry.getValue() + value));

EDIT:

Better use .merge (suggested by lexicore in this comment), which avoids unnecessary runs of the compute function for absent keys:

HM2.entrySet()
.forEach(entry -> HM1.merge(
entry.getKey(),
entry.getValue(),
(key, value) -> entry.getValue() + value));

Either of the above will update HM1 to have the final result.

System.out.println(HM1);

Outpus:

{bar=1, foo=2, main=1}


Related Topics



Leave a reply



Submit