Considere o seguinte Java HashMap.
Map<String, String> unsortMap = new HashMap<String, String>();
unsortMap.put("Z", "z");
unsortMap.put("B", "b");
unsortMap.put("A", "a");
unsortMap.put("C", "c");
Agora eu gostaria de classificar este mapa por Key. Uma opção é para mim usar um TreeMap para esta finalidade.
Map<String, String> treeMap = new TreeMap<String, String>(unsortMap);
Outra opção é para eu usar Java Streams com Ordenado (), como segue.
Map<String, Integer> sortedMap = new HashMap<>();
unsortMap.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey())
.forEachOrdered(x -> sortedMap.put(x.getKey(), x.getValue()));
Fora destes dois, qual opção é a preferida e por quê (pode ser em termos de desempenho)?
Obrigado
Como apontado por outros de dumping o fluxo ordenado de entradas em um regular HashMap
não faria nada ... LinkedHashMap
é a escolha lógica.
No entanto, uma alternativa às abordagens acima é fazer pleno uso da Corrente Collectors
API.
Collectors
tem um toMap
método que permite que você forneça uma implementação alternativa para o Map
. Então, ao invés de um HashMap
, você pode pedir um LinkedHashMap
assim:
unsortedMap.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey())
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(v1, v2) -> v1, // you will never merge though ask keys are unique.
LinkedHashMap::new
));
Entre usando um TreeMap vs LinkedHashMap ... A complexidade da construção é provável que seja o mesmo algo como O (n log n) ... Obviamente, a TreeMap
solução é uma abordagem melhor, se você pretende continuar a adicionar mais elementos a ele ... Eu acho que você deve ter começado com um TreeMap
nesse caso. A LinkedHashMap
opção tem a vantagem de pesquisa vai ser O (1) sobre a ligação, nem o mapa originais não seleccionadas enquanto como TreeMap de algo como O(log n)
isso, se você precisa manter o mapa não ordenada em torno de pesquisa eficiente enquanto que se você construir a LinkedHashMap você poderia atirar o mapa originais não seleccionadas (poupando assim alguma memória).
Para tornar as coisas um pouco mais eficiente com LinkedHashMap
você deve fornecer um bom estimador do tamanho exigido no construção de modo que não há necessidade de redimensionamento dinâmico, então ao invés de LinkedHashMap::new
você diz () -> new LinkedHashMap<>(unsortedMap.size())
.
Eu sou minha opinião, o uso de um TreeMap
é mais puro ... como mantém o código menor de modo a menos que haja problema de desempenho real que poderia ser abordado usando o não triados e classificadas abordagem mapa vinculado eu usaria o Tree
.