Collectors.toMap and Duplicate Keys
javaJavainterview-prepintermediatejava
What happens when two list elements produce the same map key, and three ways to handle it: keep the first, combine the values, or group them into lists.
import java.util.*;
import java.util.stream.*;
public class ListToMap {
record Product(String sku, String name) { }
public static void main(String[] args) {
List<Product> products = List.of(
new Product("A1", "Pen"), new Product("B2", "Book"), new Product("A1", "Pencil"));
try {
products.stream().collect(Collectors.toMap(Product::sku, Product::name));
} catch (IllegalStateException e) {
System.out.println(e.getMessage()); // Duplicate key A1 (attempted merging values Pen and Pencil)
}
// 1. Keep the first value. The fourth argument keeps the insertion order.
Map<String, String> keepFirst = products.stream()
.collect(Collectors.toMap(Product::sku, Product::name, (first, second) -> first, LinkedHashMap::new));
System.out.println(keepFirst); // {A1=Pen, B2=Book}
// 2. Combine the values with a merge function.
Map<String, String> joined = products.stream()
.collect(Collectors.toMap(Product::sku, Product::name, (a, b) -> a + " / " + b, LinkedHashMap::new));
System.out.println(joined); // {A1=Pen / Pencil, B2=Book}
// 3. Group into lists, so nothing is lost.
Map<String, List<String>> grouped = products.stream()
.collect(Collectors.groupingBy(Product::sku, LinkedHashMap::new,
Collectors.mapping(Product::name, Collectors.toList())));
System.out.println(grouped); // {A1=[Pen, Pencil], B2=[Book]}
}
}