0
0
JavaHow-ToBeginner · 3 min read

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:

ParameterDescription
keyMapperFunction to extract the key from each element
valueMapperFunction 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.