How to Use Collectors.toMap in Java: Simple Guide with Examples
Use
Collectors.toMap to convert a Java Stream into a Map by specifying how to get the key and value from each element. It takes two functions: one for the key and one for the value, and optionally a merge function to handle duplicate keys.Syntax
The basic syntax of Collectors.toMap requires two functions:
- keyMapper: a function to extract the key from each stream element.
- valueMapper: a function to extract the value from each stream element.
Optionally, you can provide a third function to handle duplicate keys by merging values.
java
Collectors.toMap(keyMapper, valueMapper) Collectors.toMap(keyMapper, valueMapper, mergeFunction)
Example
This example shows how to convert a list of strings into a map where the key is the string itself and the value is its length.
java
import java.util.*; import java.util.stream.*; public class ToMapExample { public static void main(String[] args) { List<String> fruits = Arrays.asList("apple", "banana", "cherry", "date"); Map<String, Integer> fruitLengthMap = fruits.stream() .collect(Collectors.toMap( fruit -> fruit, // key: the fruit name fruit -> fruit.length() // value: length of the fruit name )); System.out.println(fruitLengthMap); } }
Output
{apple=5, banana=6, cherry=6, date=4}
Common Pitfalls
A common mistake is having duplicate keys in the stream, which causes IllegalStateException. To fix this, provide a merge function to combine values for duplicate keys.
java
import java.util.*; import java.util.stream.*; public class ToMapDuplicateKey { public static void main(String[] args) { List<String> words = Arrays.asList("apple", "banana", "apricot", "blueberry"); // This will throw IllegalStateException because "apple" and "apricot" start with 'a' // Map<Character, String> map = words.stream() // .collect(Collectors.toMap( // word -> word.charAt(0), // word -> word // )); // Correct way: provide a merge function to join values with the same key Map<Character, String> map = words.stream() .collect(Collectors.toMap( word -> word.charAt(0), word -> word, (existing, replacement) -> existing + ", " + replacement )); System.out.println(map); } }
Output
{a=apple, apricot, b=banana, blueberry}
Quick Reference
Summary of Collectors.toMap usage:
| Parameter | Description |
|---|---|
| keyMapper | Function to extract the key from each element |
| valueMapper | Function to extract the value from each element |
| mergeFunction (optional) | Function to merge values if keys duplicate |
| mapSupplier (optional) | Supplier to create a specific Map implementation |
Key Takeaways
Use Collectors.toMap with key and value functions to convert streams to maps.
Provide a merge function to handle duplicate keys and avoid exceptions.
The keyMapper extracts keys, valueMapper extracts values from stream elements.
You can specify a mapSupplier to choose the map type if needed.
Always test with data that might have duplicate keys to prevent runtime errors.