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, or befriend him on Facebook or Google Plus. If you like my tutorials, consider make a donation to these charities.

Comments

Leave a Reply

avatar
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” }

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)

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

trackback
Java 8 – Convert Map to List

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

Manishkumar Modi
Guest
Manishkumar Modi

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

visitor
Guest
visitor

no matter we comment mkyong never response :P