Codectionary / Developer documentation / Java

Duplicate Keys in Collectors.toMap

Choose an explicit merge rule when several stream elements produce the same map key.

What it is and why to use it

Converting records into a map requires deciding what to do when keys repeat. The two-function toMap overload throws IllegalStateException on duplicate keys. An overload with a merge function lets the application combine values or deliberately choose which value to retain.

How it works

The key mapper uses the first letter of each word. The value mapper supplies its length. Integer::sum combines values for a repeated initial, and LinkedHashMap::new preserves first-key encounter order. The merge rule is a business decision; summing is correct here because the desired result is total letters per initial.

Common mistakes and limitations

Do not silently keep the first value unless discarding later values is intended. Empty strings would make this substring operation fail; validate input when it is not controlled. Null values are not supported by this collection recipe.

Try it and keep learning

Save the complete example below as Main.java. With a JDK supporting Java 17, compile using javac --release 17 Main.java, then run java Main from the same directory. These examples need only the standard library and fixed input; they do not require packages, files or network access.

Syntax

Collectors.toMap(keyMapper, valueMapper, mergeFunction, LinkedHashMap::new)

Examples

Duplicate Keys in Collectors.toMap

Complete Main.java example — Java 17 or later, without preview features.

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Main {
  public static void main(String[] args) {
    Map<String, Integer> totals = List.of("Java", "Jam", "Ruby").stream()
        .collect(Collectors.toMap(word -> word.substring(0, 1),
            String::length, Integer::sum, LinkedHashMap::new));
    System.out.println(totals);
  }
}
  1. Java maps to J and 4; Jam maps to J and 3.
  2. The merge function sums 4 and 3, giving J a total of 7.
  3. Ruby creates R with 4. The printed order follows the first encounter of J and R, making the result deterministic.
  4. Expected output: {J=7, R=4}

Best practices

  • Define and explain duplicate-key behaviour.
  • Prefer groupingBy when all original records must be retained.

Runtime & versions

Java Virtual Machine. Feature availability depends on the language and runtime version used by your project; consult the official reference below.

Java Language Specification

Specifications & further reading