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.