Come mantenere l’ordine di ripetizione di un elenco quando si utilizza Collections.toMap () su un stream?

Sto creando una Map da un List come segue:

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

Voglio mantenere lo stesso ordine di iterazione List . Come posso creare una LinkedHashMap usando i metodi Collectors.toMap() ?

La versione a 2 parametri di Collectors.toMap() usa una HashMap :

 public static  Collector> toMap( Function keyMapper, Function valueMapper) { return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new); } 

Per utilizzare la versione a 4 parametri , è ansible sostituire:

 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 per renderlo un po ‘più pulito, scrivi un nuovo metodo toLinkedMap() e usa quello:

 public class MoreCollectors { public static  Collector> toLinkedMap( Function keyMapper, Function valueMapper) { return Collectors.toMap( keyMapper, valueMapper, (u, v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); }, LinkedHashMap::new ); } } 

Puoi Combiner facilmente passando il tuo Supplier , Accumulator e Combiner al metodo di collect del tuo stream come di seguito:

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