# How to convert a list to a map in Java

By Atta Ur Rehman Shah (https://attacomsian.com/about). Published Oct 29, 2022. Topics: Java.
Canonical URL: https://attacomsian.com/blog/java-convert-list-to-map

> Learn how to use the Collectors.toMap() method from Streams API 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:

```java
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:

```java
// 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:

```java
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:

```java
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()`:

```java
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,

```java
(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:

```java
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}
```
