Menu

Java HashMap: put, get, iterar e padrões comuns

Como usar o HashMap do Java para buscas chave-valor: put, get, getOrDefault, containsKey, iterar sobre entradas e os padrões que você mais vai usar.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

Um Map armazena pares chave-valor

Um HashMap (de java.util) armazena associações: cada chave é mapeada para um valor, e você busca os valores pela chave em tempo aproximadamente constante. Pense em um dicionário: a palavra é a chave e a definição é o valor.

Os dois parâmetros de tipo são <KeyType, ValueType>. Aqui as chaves são String e os valores são Integer. Assim como com ArrayList, você normalmente declara a variável com o tipo da interface Map e constrói um HashMap.

put, get e sobrescrita

Duas coisas para internalizar:

  • Uma chave é única. put com uma chave existente substitui o valor dela e retorna o antigo.
  • get em uma chave inexistente retorna null, não um erro. Fazer o auto-unboxing desse null para um int lança uma NullPointerException, uma fonte comum de bugs.

getOrDefault evita a armadilha do null

Em vez de verificar null toda vez, peça um valor padrão:

Essa é a maneira mais limpa de lidar com buscas de itens "talvez presentes", e leva diretamente ao padrão mais famoso de HashMap.

Contar ocorrências

Contar quantas vezes cada item aparece é a tarefa clássica de um HashMap:

O padrão map.put(key, map.getOrDefault(key, 0) + 1) se lê como "pegue a contagem atual (ou zero), some um e guarde de volta". Um equivalente mais elegante é counts.merge(word, 1, Integer::sum).

Verificar e remover

putIfAbsent(key, value) só escreve quando a chave não existe, útil para inicialização preguiçosa.

Percorrer um HashMap

O laço mais comum percorre entrySet(), fornecendo cada chave e valor juntos:

Se você precisa apenas das chaves ou apenas dos valores:

Você também pode usar forEach com uma lambda: ages.forEach((name, age) -> System.out.println(name + ": " + age));.

O HashMap não mantém a ordem

Um HashMap não garante nenhuma ordem de iteração: é a que o hashing produz, e ela pode mudar entre execuções. Se você precisa de uma ordem previsível:

  • LinkedHashMap preserva a ordem de inserção.
  • TreeMap mantém as chaves ordenadas pela ordem natural (ou por um Comparator que você fornecer).

As três implementam a interface Map, então trocar entre elas é uma alteração de uma única linha no construtor.

As chaves precisam ser hasheáveis

HashMap encontra as entradas fazendo o hash da chave, então o hashCode() e o equals() de uma chave precisam ser consistentes entre si. Tipos nativos como String e Integer já fazem isso corretamente. Se você usar sua própria classe como chave, sobrescreva tanto equals quanto hashCode; caso contrário, dois objetos que são "iguais" em significado vão parar em buckets diferentes e suas buscas vão falhar de forma misteriosa.

A seguir: HashSet

Um HashMap responde "qual valor está armazenado sob esta chave?". Quando você só se importa se algo está presente ou não (um conjunto de valores únicos, sem dados associados), a ferramenta é HashSet, que vem a seguir.

Perguntas frequentes

Como criar um HashMap em Java?

Declare-o com dois parâmetros de tipo (o tipo da chave e o tipo do valor) e chame o construtor: Map<String, Integer> ages = new HashMap<>();. Depois adicione entradas com ages.put("Ada", 36); e leia-as com ages.get("Ada");. Importe java.util.HashMap e java.util.Map.

Como percorrer um HashMap em Java?

Itere sobre map.entrySet() com um laço for-each para obter cada chave e valor juntos: for (Map.Entry<String, Integer> e : map.entrySet()) { ... }, lendo e.getKey() e e.getValue(). Você também pode percorrer map.keySet() para obter só as chaves ou map.values() para obter só os valores. Lembre-se de que um HashMap não mantém a ordem de inserção.

Qual é a diferença entre get e getOrDefault?

get(key) retorna o valor de uma chave, ou null se a chave não existir, o que pode causar uma NullPointerException se você usar o resultado diretamente. getOrDefault(key, fallback) retorna o valor se estiver presente; caso contrário, retorna o valor padrão que você passar, evitando a verificação de null. É especialmente útil para contagem: counts.put(c, counts.getOrDefault(c, 0) + 1).

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR