Classificando Map por valores em Java: 5 erros fatais e suas soluções

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Classificação de Map por valores em Java: como não pisar nos mesmos ancinhos (e nos novos também)

\n\n

«Preciso classificar um HashMap por valores!» — esta pergunta no Stack Overflow acumula milhares de visualizações e dezenas de respostas. Parece que poderia ser mais simples? Pegue um Map, classifique por values()… e ganhe uma dor de cabeça. Porque classificar um Map por valores em Java é aquela tarefa onde iniciantes (e até desenvolvedores experientes) cometem os mesmos erros repetidamente.

\n\n

Neste artigo, analisaremos os 5 erros mais comuns ao classificar HashMap por valores, mostraremos as soluções corretas e forneceremos modelos de código prontos. Vamos lá!

\n\n

Erro nº1: Tentativa ingênua de classificar o próprio HashMap

\n\n

O erro mais comum é pensar que um HashMap pode ser classificado "no local". HashMap não garante a ordem dos elementos — esta é sua propriedade fundamental. Você não pode simplesmente chamar sort() em um HashMap, porque ele não possui esse método.

\n\n

Veja como NÃO fazer:

\n\n
// ❌ ERRO: HashMap não pode ser classificado diretamente\nMap<String, Integer> scores = new HashMap<>();\nscores.put("Alice", 95);\nscores.put("Bob", 80);\nscores.put("Charlie", 90);\n\n// Este método não existe!\n// scores.sort(...); // Erro de compilação
\n\n

Por que isso não funciona? HashMap usa hashing para armazenar pares chave-valor. A ordem é determinada pelos códigos hash das chaves e pode mudar ao adicionar novos elementos. Classificar um Map por valores só é possível criando uma nova estrutura de dados — por exemplo, LinkedHashMap.

\n\n

Solução correta: criando um novo LinkedHashMap

\n\n
// ✅ CORRETO: classificamos Entry e salvamos em LinkedHashMap\nMap<String, Integer> sortedMap = scores.entrySet()\n    .stream()\n    .sorted(Map.Entry.comparingByValue())\n    .collect(Collectors.toMap(\n        Map.Entry::getKey,\n        Map.Entry::getValue,\n        (e1, e2) -> e1, // resolvendo conflitos (se houver chaves duplicadas)\n        LinkedHashMap::new // mantendo a ordem de inserção\n    ));\n\nSystem.out.println(sortedMap);\n// {Bob=80, Charlie=90, Alice=95} — classificado em ordem crescente!
\n\n

Erro nº2: Esquecer o LinkedHashMap ao coletar

\n\n

Até desenvolvedores Java experientes às vezes escrevem este código:

\n\n
// ⚠️ QUASE CORRETO, mas tem um detalhe\nMap<String, Integer> result = scores.entrySet()\n    .stream()\n    .sorted(Map.Entry.comparingByValue())\n    .collect(Collectors.toMap(\n        Map.Entry::getKey,\n        Map.Entry::getValue\n    )); // Por padrão, Collectors.toMap() cria um HashMap!
\n\n

Qual é o problema? Collectors.toMap() sem especificar um fornecedor (supplier) cria um HashMap. E HashMap não garante ordem! Sua classificação será executada, mas o resultado pode parecer não classificado. Este é um dos erros mais traiçoeiros em Java ao classificar Map.

\n\n

Como corrigir

\n\n

Sempre especifique explicitamente LinkedHashMap::new como quarto argumento:

\n\n
// ✅ GARANTIDAMENTE CORRETO\nMap<String, Integer> result = scores.entrySet()\n    .stream()\n    .sorted(Map.Entry.comparingByValue())\n    .collect(Collectors.toMap(\n        Map.Entry::getKey,\n        Map.Entry::getValue,\n        (oldVal, newVal) -> oldVal,\n        LinkedHashMap::new // Ponto crucial!\n    ));
\n\n

Erro nº3: Classificar por valores quando eles não são Comparable

\n\n

Suponha que você tenha Map<String, CustomObject>. Você escreve:

\n\n
// ❌ ERRO: CustomObject não implementa Comparable\nMap<String, CustomObject> map = new HashMap<>();\n// ...\nmap.entrySet().stream()\n    .sorted(Map.Entry.comparingByValue()) // Erro de compilação!\n                

Blogs

Book Recommendations