How to Convert Stream to Specific Map Implementation in Java


How can we convert a Stream to a TreeMap or LinkedHashMap or any Map implementation in Java?

Suppose we have a Stream of integers.

Stream<Integer> stream = Arrays.asList(1, 2).stream();

Convert Stream to Map

We can use Stream.collect() and Collectors.toMap() to collect stream elements into a map.

Map<Integer, Integer> map = stream.collect(
  Collectors.toMap(
    num -> getKey(num),
    num -> getValue(num)
  )
);

If we’re collecting map entries into another map, we can use the static Map.Entry::getKey and Map.Entry::getValue functions.

Map<Integer, Integer> map = stream.collect(
  Collectors.toMap(
    Map.Entry::getKey, 
    Map.Entry::getValue
  )
);

Convert Stream to TreeMap

To convert to a specific map implementation, we’ll need to specify the mergeFunction and mapSupplier, the third and fourth arguments, respectively.

Map<Integer, Integer> map = stream.collect(
  Collectors.toMap(
    num -> getKey(num),
    num -> getValue(num),
    (oldValue, newValue) -> newValue,
    TreeMap::new
  )
);

The (oldValue, newValue) -> newValue allows the collector to resolve duplicate keys, and in this case, returns the value of the second key.

The mapSupplier provides a new, empty Map instance into which the results will be inserted.

Convert Stream to LinkedHashMap

Converting to other implementations is just as easy.

Map<Integer, Integer> map = stream.collect(
  Collectors.toMap(
    num -> getKey(num),
    num -> getValue(num),
    (oldValue, newValue) -> newValue,
    LinkedHashMap::new
  )
);

General-purpose map implementations include HashMap, TreeMap, and LinkedHashMap. Special-purpose map implementations include EnumMap, WeakHashMap, and IdentityHashMap. There are also concurrent map implementations: ConcurrentMap and ConcurrentHashMap.