How to merge two Maps in Java 8

The Map interface has been extended with the “merge” function in Java 8. Let’s see an example on how to use it.

Consider the following Empolyee class:

public class Employee
{
    private UUID id;
    private String name;
    private int age;

    public Employee(UUID id, String name, int age)
    {
        this.id = id;
        this.name = name;
        this.age = age;
    }
        
    public UUID getId()
    {
        return id;
    }

    public void setId(UUID id)
    {
        this.id = id;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }    
    
    public int getAge()
    {
        return age;
    }

    public void setAge(int age)
    {
        this.age = age;
    }
}

Let’s say that we have the following two maps where the key is an indicator of the employees’ performance and the value is the list of employees that fall into that category:

List<Employee> averageMapOne = new ArrayList<>();
averageMapOne.add(new Employee(UUID.randomUUID(), "Elvis", 50));
averageMapOne.add(new Employee(UUID.randomUUID(), "Marylin", 18));
List<Employee> poorMapOne = new ArrayList<>();
poorMapOne.add(new Employee(UUID.randomUUID(), "Mario", 43));
poorMapOne.add(new Employee(UUID.randomUUID(), "John", 35));
List<Employee> excellentMapOne = new ArrayList<>();
excellentMapOne.add(new Employee(UUID.randomUUID(), "Julia", 55));
List<Employee> okMapOne = new ArrayList<>();
okMapOne.add(new Employee(UUID.randomUUID(), "Nick", 43));
okMapOne.add(new Employee(UUID.randomUUID(), "Richard", 61));

Map<String, List<Employee>> employeeMapOne = new HashMap<>();
employeeMapOne.put("average", averageMapOne);
employeeMapOne.put("poor", poorMapOne);
employeeMapOne.put("excellent", excellentMapOne);
employeeMapOne.put("OK", okMapOne);

List<Employee> averageMapTwo = new ArrayList<>();
averageMapTwo.add(new Employee(UUID.randomUUID(), "Lotta", 52));
averageMapTwo.add(new Employee(UUID.randomUUID(), "Eva", 42));
averageMapTwo.add(new Employee(UUID.randomUUID(), "Mark", 24));
List<Employee> poorMapTwo = new ArrayList<>();
poorMapTwo.add(new Employee(UUID.randomUUID(), "Anna", 20));
List<Employee> excellentMapTwo = new ArrayList<>();
excellentMapTwo.add(new Employee(UUID.randomUUID(), "Bertil", 28));
excellentMapTwo.add(new Employee(UUID.randomUUID(), "Cecilia", 36));
excellentMapTwo.add(new Employee(UUID.randomUUID(), "Edit", 21));

Map<String, List<Employee>> employeeMapTwo = new HashMap<>();

employeeMapTwo.put("average", averageMapTwo);
employeeMapTwo.put("poor", poorMapTwo);
employeeMapTwo.put("excellent", excellentMapTwo);

Our goal is to merge map 2 into map 1 in way that all employees that fall into the same category will have all employees in a joined list. E.g. “average” will have 5 employees: Elvis, Marylin, Lotta, Eva and Mark.

The solution requires an understanding of the Java Stream API.

Here’s an explanation of the below bit of code:

  • We open a stream on the entry set of the first map
  • Then we iterate through the map using the forEach method
  • We pass a lambda expression into forEach where we want to do “something” with each entry in the entry set
  • This “something” is the actual merge operation of map 2
  • The merge operation accepts a key and a value which will be the key and value of map 1
  • Merge also accepts a BiFunction which will be used in case the key already exists in map 2
  • In this function we pass in the lists from map 1 and map 2, add the contents of map 1 into map 2 and return the new list

Here’s the code that will do the trick:

employeeMapOne.entrySet().stream()
        .forEach(entry -> employeeMapTwo.merge(entry.getKey(), entry.getValue(),
                (listTwo, listOne) ->
                        {
                            listOne.addAll(listTwo);
                            return listOne;
                        }));

View all posts related to Java here.

Advertisements

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

ultimatemindsettoday

A great WordPress.com site

iReadable { }

.NET Tips & Tricks

Robin Sedlaczek's Blog

Developer on Microsoft Technologies

HarsH ReaLiTy

A Good Blog is Hard to Find

Softwarearchitektur in der Praxis

Wissenswertes zu Webentwicklung, Domain-Driven Design und Microservices

the software architecture

thoughts, ideas, diagrams,enterprise code, design pattern , solution designs

Technology Talks

on Microsoft technologies, Web, Android and others

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

Anything around ASP.NET MVC,WEB API, WCF, Entity Framework & AngularJS

Cyber Matters

Bite-size insight on Cyber Security for the not too technical.

Guru N Guns's

OneSolution To dOTnET.

Johnny Zraiby

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.

%d bloggers like this: