Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java Collectors.toMap: choose a duplicate-key rule

Last updated: 5 Oct 20264 min read
tutorial
AdvancedBy AITrove Editorial

Collectors.toMap needs an explicit merge function when distinct input records can produce the same map key.

Name the conflict policy

Two shipment updates can share an order ID. The two-argument collector throws when that happens; this is often useful during validation, but it is not a merge strategy. A merge function must state whether the earliest update, latest update or a combined value wins.

This program keeps the larger revision number. That policy is independent of input order for unequal revisions, unlike a last-write-wins lambda that depends on encounter order. If equal revisions carry different payloads, reject the conflict instead of silently picking one. Map key contracts still apply.

Avoid pretending the default map is ordered

This example looks up keys directly and prints explicit fields. The basic toMap overload does not promise the map implementation or iteration order. Use an explicit map supplier when presentation order is part of the result.

Working program

Java
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class ShipmentRevisionIndex {
    static final class Revision {
        final String orderId;
        final int number;
        Revision(String orderId, int number) {
            this.orderId = orderId;
            this.number = number;
        }
    }
    public static void main(String[] args) {
        List<Revision> updates = Arrays.asList(
                new Revision("ORD-47", 2), new Revision("ORD-82", 1),
                new Revision("ORD-47", 4));
        Map<String, Revision> newest = updates.stream().collect(Collectors.toMap(
                revision -> revision.orderId,
                revision -> revision,
                (left, right) -> left.number >= right.number ? left : right));
        System.out.println("ORD-47=" + newest.get("ORD-47").number);
        System.out.println("orders=" + newest.size());
    }
}

Output

Output
ORD-47=4
orders=2

Cost and ownership

Collection is O(n) expected time with a hash map and O(k) space for k distinct order IDs; collision-heavy keys can change practical costs. A merge function may run multiple times for the same key, particularly in parallel collection, so it must be associative for parallel use and free of external side effects.

Common Mistakes

  • Do not use two-argument toMap when duplicate keys are valid input.
  • Do not use a nonassociative merge policy in parallel collection.
  • Do not infer iteration order from a basic toMap result.

Read next

Java HashMap: keys, collisions, and update operations, collectors tomap order, collectors groupingby null key, Java streams: lazy pipelines and bounded results.

java
streams
collectors-tomap-duplicate-key
Storage details