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.