Friday, April 19, 2024
HomeJavaThe best way to merge two HashMap in Java 8

The best way to merge two HashMap in Java 8


You possibly can merge two Map in Java utilizing the newly added merge() perform in Java 8. This lets you copy values from one map to a different to merge each of them. It additionally present a number of flexibility to deal with duplicate keys. Within the final article, I’ve proven you how you can mix two Map in Java utilizing the putAll() methodology however there was an issue. If a key’s current in each map, then putAll() overrides the worth from the second map, which you will or could not need. The true situation is that you haven’t any management on what ought to occur if there exists duplicate keys in these Map e.g. chances are you’ll need to preserve the unique worth intact otherwise you all the time need values from second map to override values in first map, otherwise you simply need to concat or add two values to type a brand new worth. This drawback is solved by the Map.merge() methodology in JDK 8, which lets you cross a lambda expression to manage the remapping operation.

What does Map.merge() methodology work?

The merge() methodology is a default methodology added on java.util.Map interface on JDK 8. It accepts three parameters key, worth and a BiFunction which is a useful interface. If the given key isn’t already related to a worth within the map or is related to null then it associates that with the given non-null worth. 

In any other case i.e. when the secret’s already current within the map then it replaces the related worth with the outcomes of the given remapping perform. The remapping perform is the third parameter which is a BiFunction. 

In case you are new to useful programming, A BiFunction<T, U, R> accepts two arguments T and U and return a results of sort R. In case of merge, the BiFunction argument have to be the kind of values as seen right here:

BiFunction<? tremendous V,? tremendous V,? extends V> remappingFunction)

As a result of it’s a useful interface, you may cross a lambda expression to it and might do a number of issues. For instance, you may retain values from the unique map or you may add them if they’re numbers or concat them if they’re String. 

You possibly can even use merge() methodology to take away a mapping. For instance, if the remapping perform returns null then the mapping is eliminated. Equally, if If the re-mppaing perform itself throws an (unchecked) exception, the exception is rethrown, and the present mapping is left unchanged.

How to merge two Map in Java 8 - Map.merge() example

The best way to merge two HashMap in Java?

Suppose you have got two maps, first and second and also you need to merge them, for you could both to first.merge(second) or second.merge(first), each gives you the identical consequence however in case of former, second map will stay identical and in later instance first map will stay unchanged.

Let’s assume we need to do first.merge(second) however since merge want key, worth and a mapping perform, we have to iterate by the second map and name the merge() methodology for every key and worth as proven beneath:

for(Map.Entry<String, String> entry: secondMap.entrySet()){
    firstMap.merge(entry.getKey(),entry.getValue(),(v1, v2) -> v1);
}

On this case we’re maintaining the worth from first map in case of dupliate key. If you wish to use the worth from the second map for dupliate keys then you may simply use v2 within the lambda expression handed as remapping perform, as proven beneath:

for(Map.Entry<String, String> entry: secondMap.entrySet()){

  firstMap.merge(entry.getKey(), entry.getValue(), (v1, v2) -> v1);
}

If you wish to mix them utilizing “:” then you too can do like this:

for(Map.Entry<String, String> entry: secondMap.entrySet()){

firstMap.merge(entry.getKey(), 
entry.getValue(),
(v1, v2) -> (v1 + ":" + v2);

}

In brief, you have got entry to each values from first and second map and you are able to do no matter you need to do. Simply do not return null as a result of it is going to then take away the mapping from the merged map. 

Btw, you too can change the improved for loop with the forEach() methodology of Java 8, which can be obtainable to Map interface as beneath:

secondMap.forEach((key, worth) -> 
firstMap.merge(key, worth, (v1, v2) -> (v1 + " " + v2)));

That is far more clear and succinct and easier. Right here we’re iterating over second map and passing every key and worth to the merge() perform known as on first map. The forEach() perform takes a BiConsumer i.e. a perform which takes two values and return nothing. The decision to firstMap.merge() is donning precisely that. 

By the best way, you too can throw RuntimeException or AsseritionError in case of duplicate keys as proven beneath:

secondMap.forEach((key, worth) -> 

firstMap.merge(key, worth,

(v1, v2) -> {

throw new AssertionError("duplicate values for key: "+ key); })); 

This can throw following error once you run this code:

Exception in thread "predominant" java.lang.AssertionError: 
duplicate values for key: joshbloch
at Helloworld.lambda$1(Helloworld.java:55)
at java.util.HashMap.merge(HashMap.java:1253)
at Helloworld.lambda$0(Helloworld.java:55)
at java.util.HashMap.forEach(HashMap.java:1288)
at Helloworld.predominant(Helloworld.java:55)

as a result of the important thing “joshbloch” is current in each the map. Let’s have a look at a few examples of merge() methodology in Java 8 to grasp it higher. 

Java Program to merge two HashMaps utilizing Map.merge() in JDK 8

Right here is the whole Java program to reveal how you can use the merge perform in Java 8 for combining values from two map. On this case I’ve two maps, the place I’ve saved twitter handles of common Java personalities and their first and title e.g. joshbloch, which is twitter handler of Joshua Bloch, creator of Efficient Java and Java Puzzlers and BrianGoetz is twitter handler for Brian Goetz, creator of one other common Java ebook, Java Concurrency in Apply.

The primary map accommodates twitter deal with to first title mapping and second map accommodates twitter deal with to final title mapping. If each map accommodates identical deal with e.g. joshbloch and springrod is current in each map then we now have a conflict and that is the place energy of merge() perform is present cased. 

In case of first instance, we now have used worth from the primary map in case of key conflict, whereas within the second instance we now have used the worth from the second map. On the third instance, we now have mixed values from each map to create full title e.g. joshbloch mapped to Joshua Bloch in remaining map. 

import java.util.HashMap;

import java.util.Map;



public class Helloworld {



public static void predominant(String[] args) {



// first map creator to ebook

Map<String, String> firstMap = new HashMap<String, String>();

firstMap.put("joshbloch", "Joshua");

firstMap.put("reducing", "Doug");

firstMap.put("BrianGoetz", "Brian");

firstMap.put("springrod", "Rod");





System.out.println("first map: " + firstMap);



// second map - creator to ebook

Map<String, String> secondMap = new HashMap<>();

secondMap.put("joshbloch", "Bloch");

secondMap.put("mjpt777", "Thompson");

secondMap.put("springrod", "Johnson");

secondMap.put("odersky", "Odersky");

secondMap.put("seriouspony", "Sierra");



System.out.println("second map: " + secondMap);



// once you merge map, it could accommodates mapping

// from the 2 maps, however for duplicate keys

// you have got selection. You possibly can specify what would you like

// to do with values e.g. overwriting or simply concatenating them

// you may select any map to supply and vacation spot

// for instance, in beneath code, autorToBook map

// will comprise mixed worth however authorToBook2 will

// not be modified.



for(Map.Entry<String, String> entry: secondMap.entrySet()){

firstMap.merge(entry.getKey(), entry.getValue(), (v1, v2) -> v1);

}





System.out.println("merged with values retained from first 
map in case of duplicate keys: " 
+ firstMap);



// you may both use for loop or forEach methodology to merge two maps

// right here we're maintaining worth from second map in case of conflict of keys

secondMap.forEach((key, worth) -> firstMap.merge(key, worth, 
(v1, v2) -> v2)); 

System.out.println("merged with values retained from second map 
in case of duplicate keys: " 
+ firstMap);



// combining worth with an area from each the map if key's identical

secondMap.forEach((key, worth) -> firstMap.merge(key, worth, (v1, v2) 
-> (v1 + " " + v2))); 

System.out.println("merged with values retained from second map in 
case of duplicate keys: "
 + firstMap);



// btw, you too can throw unchecked exception or error in case of 
// key conflict

secondMap.forEach((key, worth) -> firstMap.merge(key, worth, (v1, v2) -> 
{throw new AssertionError("duplicate values for key: "+ key); })); 

}



}





Output:

first map: {joshbloch=Joshua, reducing=Doug, springrod=Rod, BrianGoetz=Brian}

second map: {seriouspony=Sierra, odersky=Odersky, joshbloch=Bloch, 
springrod=Johnson, mjpt777=Thompson}

merged with values retained from first map in case of duplicate keys: 
{seriouspony=Sierra, odersky=Odersky, joshbloch=Joshua, reducing=Doug, 
springrod=Rod, mjpt777=Thompson, BrianGoetz=Brian}

merged with values retained from second map in case of duplicate keys: 
{seriouspony=Sierra, odersky=Odersky, joshbloch=Bloch, reducing=Doug, 
springrod=Johnson, mjpt777=Thompson, BrianGoetz=Brian}

merged with values retained from second map in case of duplicate keys: 
{seriouspony=Sierra, odersky=Odersky, joshbloch=Joshua Bloch, 
reducing=Doug, springrod=Rod Johnson, mjpt777=Thompson, BrianGoetz=Brian}



Exception in thread "predominant" java.lang.AssertionError: 
duplicate values for key: joshbloch

at Helloworld.lambda$1(Helloworld.java:55)

at java.util.HashMap.merge(HashMap.java:1253)

at Helloworld.lambda$0(Helloworld.java:55)

at java.util.HashMap.forEach(HashMap.java:1288)

at Helloworld.predominant(Helloworld.java:55)

You possibly can see in case of first instance joshbloch=Bloch i.e. worth from first map is used, whereas in case of second instance joshbloch=Bloch, means worth from second map is used, and in case of third instance, joshbloch=Joshua Bloch, worth from each map is mixed. You can even see that the merged map accommodates entries from each the maps.

As I stated, when you do not need to deal with duplicate keys, you too can throw AssertionError to point that, although it’s best to bear in mind to print the important thing for troubleshooting goal. 

That is all about how you can merge two Map in Java. As I stated, previous to JDK 7, you should utilize the putAll() methodology to merge or mix two map however you do not have management over values if map accommodates identical keys. This drawback is solved utilizing the merge() perform in Java 8, which lets you cross a lambda expression to compute new worth. You possibly can both preserve the worth from first map, second map, or create a brand new worth by combining values from each the map. The mapping can be eliminated in case your lambda expression consider to null. 

Additional Studying

  • The best way to filter values from a map in Java?
  • The best way to type a map by keys in Java 8?
  • The best way to take away a mapping from a map in Java 8?
  • The best way to type a map by values in Java 8?
  • The best way to examine if a key exists within the map?
  • The best way to iterate over a map in Java?

Thanks for studying this text to this point. In the event you like this instance of merging two map in Java then please share with your pals and colleagues. When you have any query or suggestions then please drop a remark. 



RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments