How to convert a list to a map in Java

To convert a list of objects to a map in Java, you can use Streams API Collectors.toMap() method. Suppose, we have the following Product.java class that stores product information:

public class Product {
    private int id;
    private String name;
    private double price;

    public Product(int id, String name, double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }

    // getters and setters, equals(), toString() .... (omitted for brevity)
}

The following example demonstrates how you can create a list of Product objects and use Collectors.toMap() to convert it into a map:

// Create a list of products
List<Product> products = List.of(
        new Product(1, "Milk", 2.3),
        new Product(2, "Honey", 9.99),
        new Product(3, "Cookies", 3.5),
        new Product(4, "Noodles", 0.99)
);

// Convert list of products to map
Map<Integer, String> map = products.stream()
        .collect(Collectors.toMap(Product::getId, Product::getName));

// Print map elements
System.out.println(map);

// {1=Milk, 2=Honey, 3=Cookies, 4=Noodles}

In the above example, we used the unique id field as the Map key. You can also use the product name field as a key, as shown below:

Map<String, Double> map = products.stream()
        .collect(Collectors.toMap(Product::getName, Product::getPrice));

System.out.println(map);

// {Honey=9.99, Cookies=3.5, Milk=2.3, Noodles=0.99}

If the product list contains duplicate names, an error will be thrown by the Collectors.toMap() method:

List<Product> products = List.of(
        new Product(1, "Milk", 2.3),
        new Product(2, "Honey", 9.99),
        new Product(3, "Cookies", 3.5),
        new Product(4, "Noodles", 0.99),

        // Duplicate Product Name
        new Product(5, "Honey", 7.99)
);

Map<String, Double> map = products.stream()
        .collect(Collectors.toMap(Product::getName, Product::getPrice));

System.out.println(map);

// Exception in thread "main" java.lang.IllegalStateException: 
// Duplicate key Honey (attempted merging values 9.99 and 7.99)

To solve the duplicate key issue above, you need to pass the third argument, a merger function, to Collectors.toMap():

Map<String, Double> map = products.stream()
        .collect(Collectors.toMap(Product::getName, Product::getPrice,
                (oldValue, newValue) -> oldValue
        ));

System.out.println(map);

// {Honey=9.99, Cookies=3.5, Noodles=0.99, Milk=2.3}

Notice the line,

(oldValue, newValue) -> oldValue

Here, we specified that in case of a duplicate key, choose the old key over the new one.

If you prefer to use the new key value, use the following code:

Map<String, Double> map = products.stream()
        .collect(Collectors.toMap(Product::getName, Product::getPrice,
                (oldValue, newValue) -> newValue
        ));

System.out.println(map);

// {Honey=7.99, Cookies=3.5, Noodles=0.99, Milk=2.3}

✌️ Like this article? Follow me on Twitter and LinkedIn. You can also subscribe to RSS Feed.

You might also like...

Digital Ocean

The simplest cloud platform for developers & teams. Start with a $200 free credit.

Buy me a coffee ☕

If you enjoy reading my articles and want to help me out paying bills, please consider buying me a coffee ($5) or two ($10). I will be highly grateful to you ✌️

Enter the number of coffees below:

✨ Learn to build modern web applications using JavaScript and Spring Boot

I started this blog as a place to share everything I have learned in the last decade. I write about modern JavaScript, Node.js, Spring Boot, core Java, RESTful APIs, and all things web development.

The newsletter is sent every week and includes early access to clear, concise, and easy-to-follow tutorials, and other stuff I think you'd enjoy! No spam ever, unsubscribe at any time.