Java 8 – Convert List to Map

Few Java 8 examples to show you how to convert a List of objects into a Map, and how to handle the duplicated keys.

Hosting.java

package com.mkyong.java8

public class Hosting {

    private int Id;
    private String name;
    private long websites;

    public Hosting(int id, String name, long websites) {
        Id = id;
        this.name = name;
        this.websites = websites;
    }

    //getters, setters and toString()
}

1. List to Map – Collectors.toMap()

Create a list of the Hosting objects, and uses Collectors.toMap to convert it into a Map.

TestListMap.java

package com.mkyong.java8

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class TestListMap {

    public static void main(String[] args) {

        List<Hosting> list = new ArrayList<>();
        list.add(new Hosting(1, "liquidweb.com", 80000));
        list.add(new Hosting(2, "linode.com", 90000));
        list.add(new Hosting(3, "digitalocean.com", 120000));
        list.add(new Hosting(4, "aws.amazon.com", 200000));
        list.add(new Hosting(5, "mkyong.com", 1));

        // key = id, value - websites
        Map<Integer, String> result1 = list.stream().collect(
                Collectors.toMap(Hosting::getId, Hosting::getName));

        System.out.println("Result 1 : " + result1);

        // key = name, value - websites
        Map<String, Long> result2 = list.stream().collect(
                Collectors.toMap(Hosting::getName, Hosting::getWebsites));

        System.out.println("Result 2 : " + result2);

        // Same with result1, just different syntax
        // key = id, value = name
        Map<Integer, String> result3 = list.stream().collect(
                Collectors.toMap(x -> x.getId(), x -> x.getName()));

        System.out.println("Result 3 : " + result3);
    }
}

Output


Result 1 : {1=liquidweb.com, 2=linode.com, 3=digitalocean.com, 4=aws.amazon.com, 5=mkyong.com}
Result 2 : {liquidweb.com=80000, mkyong.com=1, digitalocean.com=120000, aws.amazon.com=200000, linode.com=90000}
Result 3 : {1=liquidweb.com, 2=linode.com, 3=digitalocean.com, 4=aws.amazon.com, 5=mkyong.com}

2. List to Map – Duplicated Key!

2.1 Run below code, and duplicated key errors will be thrown!

TestDuplicatedKey.java

package com.mkyong.java8;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class TestDuplicatedKey {

    public static void main(String[] args) {

        List<Hosting> list = new ArrayList<>();
        list.add(new Hosting(1, "liquidweb.com", 80000));
        list.add(new Hosting(2, "linode.com", 90000));
        list.add(new Hosting(3, "digitalocean.com", 120000));
        list.add(new Hosting(4, "aws.amazon.com", 200000));
        list.add(new Hosting(5, "mkyong.com", 1));
		
        list.add(new Hosting(6, "linode.com", 100000)); // new line

        // key = name, value - websites , but the key 'linode' is duplicated!?
        Map<String, Long> result1 = list.stream().collect(
                Collectors.toMap(Hosting::getName, Hosting::getWebsites));

        System.out.println("Result 1 : " + result1);

    }
}

Output – The error message below is a bit misleading, it should show “linode” instead of the value of the key.


Exception in thread "main" java.lang.IllegalStateException: Duplicate key 90000
	at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)
	at java.util.HashMap.merge(HashMap.java:1245)
	//...

2.2 To solve the duplicated key issue above, pass in the third mergeFunction argument like this :


	Map<String, Long> result1 = list.stream().collect(
                Collectors.toMap(Hosting::getName, Hosting::getWebsites,
                        (oldValue, newValue) -> oldValue
                )
        );

Output


Result 1 : {..., aws.amazon.com=200000, linode.com=90000}
Note
(oldValue, newValue) -> oldValue ==> If the key is duplicated, do you prefer oldKey or newKey?

3.3 Try newValue


	Map<String, Long> result1 = list.stream().collect(
                Collectors.toMap(Hosting::getName, Hosting::getWebsites,
                        (oldValue, newValue) -> newvalue
                )
        );

Output


Result 1 : {..., aws.amazon.com=200000, linode.com=100000}

3. List to Map – Sort & Collect

TestSortCollect.java

package com.mkyong.java8;

import java.util.*;
import java.util.stream.Collectors;

public class TestSortCollect {

    public static void main(String[] args) {

        List<Hosting> list = new ArrayList<>();
        list.add(new Hosting(1, "liquidweb.com", 80000));
        list.add(new Hosting(2, "linode.com", 90000));
        list.add(new Hosting(3, "digitalocean.com", 120000));
        list.add(new Hosting(4, "aws.amazon.com", 200000));
        list.add(new Hosting(5, "mkyong.com", 1));
        list.add(new Hosting(6, "linode.com", 100000));

        //example 1
        Map result1 = list.stream()
                .sorted(Comparator.comparingLong(Hosting::getWebsites).reversed())
                .collect(
                        Collectors.toMap(
                                Hosting::getName, Hosting::getWebsites, // key = name, value = websites
                                (oldValue, newValue) -> oldValue,       // if same key, take the old key
                                LinkedHashMap::new                      // returns a LinkedHashMap, keep order
                        ));

        System.out.println("Result 1 : " + result1);

    }
}

Output


Result 1 : {aws.amazon.com=200000, digitalocean.com=120000, linode.com=100000, liquidweb.com=80000, mkyong.com=1}

P.S In above example, the stream is sorted before collect, so the “linode.com=100000” became the ‘oldValue’.

References

  1. Java 8 Collectors JavaDoc
  2. Java 8 – How to sort a Map
  3. Java 8 Lambda : Comparator example

About the Author

author image
mkyong
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

avatar
9 Comment threads
7 Thread replies
1 Followers
 
Most reacted comment
Hottest comment thread
13 Comment authors
AntonSaurabh KulkarninipunMattZeaLot4J Recent comment authors
newest oldest most voted
Prashant
Guest
Prashant

If u have to create a map<Integer , List> this code won’t work e.g.
list.add(new Hosting(1, “liquidweb.com”, 80000));
list.add(new Hosting(1, “liquidweb1.com”, 90000));

and u want map to have 1={“liquidweb.com” ,”liquidweb1.com” }

Saurabh Kulkarni
Guest
Saurabh Kulkarni

Any solution to get Map of Key, value(as list)? I need it. as explained by Prashant

Anton
Guest
Anton

Multimap multimap = create();
entry.getValue().forEach(v -> multimap.put(v.id(), v.getid()));

Anton
Guest
Anton

Multimap multimap = ArrayListMultimap.create();
list.forEach(v -> multimap.put(v.getId(), v.getId()));

guest
Guest
guest

This not working:
Map result1 = list.stream().collect(
Collectors.toMap(Hosting::getId, Hosting));

Harsh Dadhich
Guest
Harsh Dadhich

Hosting::this –> try this

dsh
Guest
dsh

dfdh

shiguang.ma
Guest
shiguang.ma

Collectors.toMap(h -> h.getId(), h -> h)

ZeaLot4J
Guest
ZeaLot4J

Function.identity() is the best

trackback
Java 8 – Convert Map to List

[…] Java 8 – Convert List to Map […]

nipun
Guest
nipun

you should also include the scenario where duplicate key values should be added in linkedList.

Matt
Guest
Matt

Huge help, thank you sir.

visitor
Guest
visitor

no matter we comment mkyong never response :P

Neshi
Guest
Neshi

Its really nice example … could You please add also an example when we want to create a multi key map from list ? I thing it could be a really helpfull.

Manishkumar Modi
Guest
Manishkumar Modi

Hi Mkyong,
My reuirement is to convert List<Map to List
Please share example

Manishkumar Modi
Guest
Manishkumar Modi

Hi Mkyong,
My reuirement is to convert List<Map to List