I am creating a Map
from a List
as follows:
List<String> strings = Arrays.asList("a", "bb", "ccc"); Map<String, Integer> map = strings.stream() .collect(Collectors.toMap(Function.identity(), String::length));
I want to keep the same iteration order as was in the List
. How can I create a LinkedHashMap
using the Collectors.toMap()
methods?
Advertisement
Answer
The 2-parameter version of Collectors.toMap()
uses a HashMap
:
public static <T, K, U> Collector<T, ?, Map<K,U>> toMap( Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper) { return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new); }
To use the 4-parameter version, you can replace:
Collectors.toMap(Function.identity(), String::length)
with:
Collectors.toMap( Function.identity(), String::length, (u, v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); }, LinkedHashMap::new )
Or to make it a bit cleaner, write a new toLinkedMap()
method and use that:
public class MoreCollectors { public static <T, K, U> Collector<T, ?, Map<K,U>> toLinkedMap( Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper) { return Collectors.toMap( keyMapper, valueMapper, (u, v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); }, LinkedHashMap::new ); } }