Map merging is essential while working on a project that is being managed by multiple team members from different platforms. Merging of maps allows us to see modifications and the latest updated data which helps in reducing conflict. Maps store data in a key-value format, these keys play a vital role in dealing with the values having common keys in both maps. 

This guide explores different approaches to merging two maps in Java.

How to Merge Two Maps in Java?

Java offers multiple techniques to merge two maps while merging the duplication of key-value pairs may also raised. These duplications of map key-value pairs can be handled by the user using the “Lambda” expression. These approaches are explained below with proper practical implementation:

  • Method 1: Merge Two Maps Using the “Stream.concat()” Method
  • Method 2: Merge Two Maps Using the “Stream.of()” and “flatMap()” Methods
  • Method 3: Merge Two Maps Using the “collect()” and “stream()” Method
  • Method 4: Merge Two Maps Using the “putAll()” Method
  • Method 5: Merge Two Maps Using the “merge()” Method

Method 1: Merge Two Maps Using the “Stream.concat()” Method

The “Stream.concat()” method first converts the entry set to Stream for each map and then accepts these converted maps as an argument. As a result, the combined or merged form of both maps appears. To handle the common or duplicated keys, the user can apply predefined methods as well like “min”, “sum” or “max”:

import java.util.*;
import java.util.Map.Entry;
import java.util.stream.*;
//Imported Required Packages

public class Mapping {
//Method for initializing the HashMaps.
private static HashMap<String, Double> trainingTroopsClan1() {
  HashMap<String, Double> troopsFromClan1 = new HashMap<>();
  troopsFromClan1.put("Archers", 57.7);
  troopsFromClan1.put("Wizards", 52.6);
  troopsFromClan1.put("Giants", 41.2);
  troopsFromClan1.put("Dragons", 70.3);
  return troopsFromClan1;
}
private static HashMap<String, Double> trainingTroopsClan2() {
  HashMap<String, Double> troopsFromClan2 = new HashMap<>();
  troopsFromClan2.put("HogRiders", 49.8);
  troopsFromClan2.put("Dragons", 60.3);
  troopsFromClan2.put("Giants", 55.9);
  return troopsFromClan2;
}

//Performing merging operation
private static HashMap<String, Double> mergeClans(HashMap<String, Double> clan1,  HashMap<String, Double> clan2) {
  return Stream.concat(clan1.entrySet().stream(), clan2.entrySet().stream())
  .collect(Collectors.toMap(Entry::getKey, Entry::getValue, Double::sum, HashMap::new));
}

//Display Method
private static void displayLeague(String clanName, HashMap<String, Double>  troopToPlayerCountMap) {
  System.out.println("\nThe displayed Maps data: \n" + clanName + ": " +  troopToPlayerCountMap);  
}

public static void main(String[] args)
{
  HashMap<String, Double> troopsFromClan1 = trainingTroopsClan1();
  HashMap<String, Double> troopsFromClan2 = trainingTroopsClan2();
  HashMap<String, Double> participatingTroops = mergeClans(troopsFromClan1, troopsFromClan2);
  displayLeague("Clan 1", troopsFromClan1);
  displayLeague("Clan 2", troopsFromClan2);
  displayLeague("League Troops", participatingTroops);
}
}

The above code works like this:

  • First, define two “HashMap” type methods named “trainingTroopsClan1()” and “trainingTroopsClan2()”. These methods set and return values of the “troopsFromClan1” and “troopsFromClan2” hashmaps respectively.
  • Next, define the “mergeClans()” method having the return type of HashMap and it accepts two hashmaps of “clan1” and “clan2”.
  • In this method, convert the “entrysets” of both accepted hashmaps into “Stream”. After conversion, pass them into the “Stream.concat()” method.
  • Moreover, apply the “collect()” method to insert the merged keys and values in a single map. Also, use this method to add the Values for duplicate Key elements.
  • After that, define the “displayLeague()” method to display the map names and their data on the console.
  • Define a “main()” method to invoke the “trainingTroopsClan1()” and “trainingTroopsClan2()” methods. Store the returns results in corresponding hashmaps. 
  • Pass these hashmaps to the “mergeClans()” method to merge and store the result in a “participatingTroops” hashmap.
  • Finally, pass these hashmaps and their dummy clan names in the “displayLeague()” method.

The output confirms the merging of the provided original maps:

Drawbacks:

The “Stream.concat()” method creates a new merged Stream instead of modifying the original Stream. Moreover, the user uses other methods like “collect()” to handle the duplication, as the “concat()” method does not deal with duplication by itself.

Method 2: Merge Two Maps Using the “Stream.of()” and “flatMap()” Methods

The combination of “Stream.of()” and “flatMap()” methods are also used to merge two maps in Java. The “Stream.of()” method creates a combined stream containing values from both maps. Then, the “flatMap()” method creates a new stream from the returned result and generates a merged map using the “Lambda” expression:

import java.util.*;
import java.util.Map.Entry;
import java.util.stream.*;
//Imported Required Packages

public class Mapping {

//Defining two Methods for Initializing the HashMaps
private static HashMap<String, Double> trainingTroopsClan1() {
  HashMap<String, Double> troopsFromClan1 = new HashMap<>();
  troopsFromClan1.put("Archers", 57.7);
  troopsFromClan1.put("Wizards", 52.6);
  troopsFromClan1.put("Giants", 41.2);
  troopsFromClan1.put("Dragons", 70.3);
  return troopsFromClan1;
}
private static HashMap<String, Double> trainingTroopsClan2() {
  HashMap<String, Double> troopsFromClan2 = new HashMap<>();
  troopsFromClan2.put("HogRiders", 49.8);
  troopsFromClan2.put("Dragons", 60.3);
  troopsFromClan2.put("Giants", 55.9);
  return troopsFromClan2;
}
//Performing merging operation
private static HashMap<String, Double> mergeClans(HashMap<String, Double> clan1,  HashMap<String, Double> clan2) {
  HashMap<String, Double> war =
  Stream.of(clan1, clan2)
    .flatMap(mapping -> mapping.entrySet().stream())
    .collect(Collectors.toMap(Entry::getKey, Entry::getValue, Double::max, HashMap::new));
  return war;
}
//Display Method
private static void displayLeague(String clanName, HashMap<String, Double>  troopToPlayerCountMap) {
  System.out.println("\nThe displayed Maps data: \n" + clanName + ": " +  troopToPlayerCountMap);  
}

public static void main(String[] args)
{
  HashMap<String, Double> troopsFromClan1 = trainingTroopsClan1();
  HashMap<String, Double> troopsFromClan2 = trainingTroopsClan2();
  HashMap<String, Double> participatingTroops = mergeClans(troopsFromClan1, troopsFromClan2);
  displayLeague("Clan 1", troopsFromClan1);
  displayLeague("Clan 2", troopsFromClan2);
  displayLeague("League Troops", participatingTroops);
}
}

In the above code block:

  • First, create methods to define and display targeted hashmaps similar to the above section. 
  • Next, create the “mergeClans()” method that accepts two created hashmaps.
  • In it, pass the accepted hashmaps into the “Stream.of()” method and apply the “flatMap()” method to convert the maps into Stream.
  • Now, attach the “collect()” method which defines the “key”, “value”, “mergeFunction” to handle duplication, and hashmap as a “mapSupplier”. 
  • Finally, store the result in a newly created hashmap named “war”.

The generated output confirms the merging of both maps in Java:

Drawbacks of Stream.of() and “flatmap()” Methods:

The “stream.of()” method does not handle merging for many elements as it only creates a Stream for a single element. To handle this, the “flatmap()” method is used to merge more than one element. But the duplication of keys is again not possible for it. This leads to the usage of the “collect()” method. This creates a lot of ambiguity and dependency on each other.

Method 3: Merge Two Maps Using the “collect()” and “stream()” Methods

The combination of “stream()” and “collect()” methods allows users to merge two maps while handling the duplicated keys issue:

import java.util.*;
import java.util.Map.Entry;
import java.util.stream.*;
//Imported Required Packages

public class Mapping {//Defining two Methods for Initializing the HashMaps
private static HashMap<String, Double> trainingTroopsClan1() {
  HashMap<String, Double> troopsFromClan1 = new HashMap<>();
  troopsFromClan1.put("Archers", 57.7);
  troopsFromClan1.put("Wizards", 52.6);
  troopsFromClan1.put("Giants", 31.2);
  troopsFromClan1.put("Dragons", 70.3);
  return troopsFromClan1;
}

private static HashMap<String, Double> trainingTroopsClan2() {
  HashMap<String, Double> troopsFromClan2 = new HashMap<>();
  troopsFromClan2.put("HogRiders", 49.8);
  troopsFromClan2.put("Dragons", 60.3);
  troopsFromClan2.put("Giants", 55.5);
  return troopsFromClan2;
}
//Performing merging operation
private static HashMap<String, Double> mergeClans(HashMap<String, Double> clan1, HashMap<String, Double> clan2) {
  HashMap<String, Double> war = clan2.entrySet()
  .stream()
  .collect(Collectors.toMap(
Entry::getKey,
Entry::getValue,
(v1, v2) -> v1<v2 ? v2-v1 : v1-v2,
() -> new HashMap<>(clan1)));
  return war;
}
//Display Method
private static void displayLeague(String clanName, HashMap<String, Double> troopToPlayerCountMap) {
  System.out.println("\nThe displayed Maps data: \n" + clanName + ": " + troopToPlayerCountMap);
}
//Main driver Method
public static void main(String[] args)
{
  HashMap<String, Double> troopsFromClan1 = trainingTroopsClan1();
  HashMap<String, Double> troopsFromClan2 = trainingTroopsClan2();
  HashMap<String, Double> participatingTroops = mergeClans(troopsFromClan1, troopsFromClan2);
  displayLeague("Clan 1", troopsFromClan1);
  displayLeague("Clan 2", troopsFromClan2);
  displayLeague("League Troops", participatingTroops);
}
}

In the above code block:

  • First, create a targeted hashmap using separate methods and display them on the console like done in the previous example.
  • Only modify the “mergeClans()” method to adopt the “stream()” and “collect()” methods to merge the provided maps.
  • In this method, apply the “entrySet()” and “stream()” methods to the “clan2” hashmap to convert the maps into Streams.
  • Next, apply the “collect()” method with the “toMap()” method as an argument and select the maps “key” and “values”. Then, apply the Lambda expression to handle the duplicated elements. 
  • Moreover, provide the new instance of a “clan1” hashmap as a map supplier (second map whose data is going to be merged).
  • Store the generated merged map in a new hashmap named “war” and return it.

The output confirms the merging of provided hashmaps:

Method 4: Merge Two Maps Using the “putAll()” Method

The “putAll()” method of pure Java, allows users to insert all elements of the provided collection into a selected map. In our case, the provided collection is also a map. Moreover, place both maps into a final map which contains the merged version:

import java.util.*;
import java.util.Map.Entry;
import java.util.stream.*;
//Importing Required Packages

public class Mapping {
private static HashMap<String, Double> trainingTroopsClan1() {
  HashMap<String, Double> troopsFromClan1 = new HashMap<>();
  troopsFromClan1.put("Archers", 57.7);
  troopsFromClan1.put("Wizards", 52.6);
  troopsFromClan1.put("Giants", 31.2);
  troopsFromClan1.put("Dragons", 70.3);
  return troopsFromClan1;
}
private static HashMap<String, Double> trainingTroopsClan2() {
  HashMap<String, Double> troopsFromClan2 = new HashMap<>();
  troopsFromClan2.put("HogRiders", 49.8);
  troopsFromClan2.put("Dragons", 60.3);
  troopsFromClan2.put("Giants", 55.5);
  return troopsFromClan2;
}

private static HashMap<String, Double> mergeClans(HashMap<String, Double> clan1, HashMap<String, Double> clan2) {
  HashMap<String, Double> war = new HashMap<>();
  war.putAll(clan1);
  war.putAll(clan2);
  return war;
}

private static void displayLeague(String clanName, HashMap<String, Double> troopToPlayerCountMap) {
  System.out.println("\nThe displayed Maps data: \n" + clanName + ": " + troopToPlayerCountMap);
}

public static void main(String[] args)
{
  HashMap<String, Double> troopsFromClan1 = trainingTroopsClan1();
  HashMap<String, Double> troopsFromClan2 = trainingTroopsClan2();
  HashMap<String, Double> participatingTroops = mergeClans(troopsFromClan1, troopsFromClan2);
  displayLeague("Clan 1", troopsFromClan1);
  displayLeague("Clan 2", troopsFromClan2);
  displayLeague("League Troops", participatingTroops);
}
}

In the above code snippet:

  • Modify the “mergeClans()” method of the previous example to use the “putAll()” method.
  • In this method, create a new hashmap named “war”. 
  • Then, apply the “putAll()” method on this “war” hashmap and pass the targeted hashmaps as parameters. 
  • Once passed, the merged maps for targeted hashmaps get generated and stored in the “war” hashmap. In the end, return this hashmap using the “return” keyword.

The rest of the code remains the same as described in the previous examples.

Output:

Drawbacks of putAll() Method

It does not handle the duplication of keys while merging the maps and displays the one that comes later to get merged.

Method 5: Merge Two Maps Using the “merge()” Method

The “merge()” method selects the key-value pair of both maps and inserts them into a new map. Moreover, it allows the use of lambda expressions to handle the duplication of keys in both maps. For instance, the duplicated key values are multiplied by each other in the below code snippet:

import java.util.*;
import java.util.Map.Entry;
import java.util.stream.*;
//Importing Required Packages
public class Mapping {//Initializing the HashMaps
private static HashMap<String, Double> trainingTroopsClan1() {
  HashMap<String, Double> troopsFromClan1 = new HashMap<>();
  troopsFromClan1.put("Archers", 57.7);
  troopsFromClan1.put("Wizards", 52.6);
  troopsFromClan1.put("Giants", 41.8);
  troopsFromClan1.put("Dragons", 70.3);
  return troopsFromClan1;
}
private static HashMap<String, Double> trainingTroopsClan2() {
  HashMap<String, Double> troopsFromClan2 = new HashMap<>();
  troopsFromClan2.put("HogRiders", 49.8);
  troopsFromClan2.put("Dragons", 60.3);
  troopsFromClan2.put("Giants", 55.9);
  return troopsFromClan2;
}
//Merging Method
private static HashMap<String, Double> mergeClans(HashMap<String, Double> clan1, HashMap<String, Double> clan2) {
  HashMap<String, Double> war = new HashMap<>(clan1);
  clan2.forEach((key, val) ->
  war.merge(
  key,
  val,
  (val1, val2) -> val1 * val2)
  );
  return war;
}
private static void displayLeague(String clanName, HashMap<String, Double> troopToPlayerCountMap) {
  System.out.println("\nThe displayed Maps data: \n" + clanName + ": " + troopToPlayerCountMap);
}
//Main method
public static void main(String[] args)
{
  HashMap<String, Double> troopsFromClan1 = trainingTroopsClan1();
  HashMap<String, Double> troopsFromClan2 = trainingTroopsClan2();
  HashMap<String, Double> participatingTroops = mergeClans(troopsFromClan1, troopsFromClan2);
  displayLeague("Clan 1", troopsFromClan1);
  displayLeague("Clan 2", troopsFromClan2);
  displayLeague("League Troops", participatingTroops);
}
}

The working of the above code is written below:

  • First, create separate methods to define hashmaps and display these hashmaps on a console similar to the first example.
  • Then, define a “mergeClans()” method and inside it create a new hashmap “war” to store the reference of a “clan1” hashmap.
  • Now, apply the “forEach()” method over the “clan2” hashmap and pass the lambda function. This function selects the “key” and “val” of each element and applies the “merge()” method over the “war” map to pass the selected values.
  • The “merge()” method also contains a lambda expression. This inserts the elements according to the key-value pairs and handles the duplicated key elements. 
  • Finally, return the merged map “war” from the method.

The output illustrates the merging of two maps in Java:

Drawbacks of merge() Method

The “merge()” method can be more complex and makes code hard to read when it comes to performing different operations over duplicated keys. As it does not provide any built-in methods to perform specific tasks which increases the line of code and consumes more time.

That’s all about the procedure to merge two maps in Java.

Conclusion

To merge two maps in Java, there are three main approaches “Java 8 Stream API”, “putAll()”, and “merge()”. To use the Stream API methods named “concat()”, “Stream.of()” and “flatMap()”, or “stream()”. These methods are a little complex but provide full control over the mapping process and provide freedom to handle the common keys. In contrast, the “putAll()” method is a lot easier but it does not handle the map’s common keys. Besides, the “merge()” method offers full control and may become complex when dealing with common keys. This guide has illustrated all approaches to merging two maps in Java.