¿Cómo guardo el orden de iteración de una lista cuando uso Collections.toMap () en una secuencia?

Estoy creando un Map partir de una List siguiente manera:

 List strings = Arrays.asList("a", "bb", "ccc"); Map map = strings.stream() .collect(Collectors.toMap(Function.identity(), String::length)); 

Quiero mantener el mismo orden de iteración que estaba en la List . ¿Cómo puedo crear un LinkedHashMap usando los métodos Collectors.toMap() ?

La versión de 2 parámetros de Collectors.toMap() usa un HashMap :

 public static  Collector> toMap( Function< ? super T, ? extends K> keyMapper, Function< ? super T, ? extends U> valueMapper) { return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new); } 

Para usar la versión de 4 parámetros , puede reemplazar:

 Collectors.toMap(Function.identity(), String::length) 

con:

 Collectors.toMap( Function.identity(), String::length, (u, v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); }, LinkedHashMap::new ) 

O para que sea un poco más limpio, escriba un toLinkedMap() nuevo toLinkedMap() y use eso:

 public class MoreCollectors { public static  Collector> 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 ); } } 

Puede lograrlo fácilmente transfiriendo su propio Supplier , Accumulator y Combiner al método de collect de su transmisión como se muestra a continuación:

 final LinkedHashMap map = strings.stream() .collect( LinkedHashMap::new, //Supplier (mapp, itemVar) -> mapp.put(itemVar, itemVar.length()), //Accumulator Map::putAll //Combiner );