Publicado em
- 6 min read
Map e HashMap em Java: Entenda tudo sobre essa estrutura de dados

Introdução
Nesse artigo, vamos conhecer o que é a interface Map e uma de suas implementações mais utilizadas: o HashMap. Detalheremos também como funcionam seus prinicipais métodos.
O que é um Map em Java?
A interface Map<K, V> representa uma estrutura de dados que mapeia chaves (keys - K) para valores (values - V). Diferente de listas ou conjuntos, um Map não armazena elementos isolados, mas sim pares associados: para cada chave, existe um único valor correspondente.
Essa estrutura é ideal quando você quer associar identificadores únicos (como nomes, códigos ou IDs) a dados relacionados, como idade, descrição ou objetos completos.

Representação gráfica
Imagine o cenário onde vamos armazenar a idade das pessoas em um mapa, internamente no Map ficaria assim:
+-----------+------------------- +
| Chave | Valor |
+-----------+------------------- +
| "Ana" | 25 |
| "Bruno" | 32 |
| "Carlos" | 32 |
+-----------+------------------- +
Essa estrutura funciona como uma tabela interna onde:
- As chaves são únicas (não se repetem).
- Os valores podem se repetir (duas pessoas podem ter a mesma idade, por exemplo).
- É possível buscar rapidamente o valor associado a uma chave, como map.get(“Bruno”) → 32.
Mapas imutáveis
Alguns métodos estáticos permitem criar mapas imutáveis de forma prática. Esses mapas possuem as seguintes características:
- Não podem ser modificados: não é possível adicionar, remover ou alterar chaves e valores — qualquer tentativa lança uma UnsupportedOperationException.
- Não aceitam null como chave ou valor.
- Rejeitam chaves duplicadas durante a criação, gerando uma IllegalArgumentException.
- A ordem de iteração não é garantida e pode variar.
Map.of()
Através desse método estático, podemos criar um novo mapa imutável contendo no máximo 10 mapeamentos (pares de chave-valor):
//Mapa de traduções
Map<String, String> dicionario = Map.of("cachorro", "dog", "gato", "cat");
System.out.println(dicionario);
//saída: {gato=cat, cachorro=dog}
Map.ofEntries()
Através desse método estático, podemos criar um novo mapa imutável a partir de entradas de chave-valor fornecidos:
//Mapa de pontos de jogadores
Map<String, Integer> pontuacao = Map.ofEntries(
Map.entry("Player_1", 100),
Map.entry("Player_2", 124),
Map.entry("Player_3", 50)
);
System.out.println(pontuacao);
//saída: {Player_3=50, Player_2=124, Player_1=100}
Map.copyOf()
Através desse método estático, criamos um novo mapa imutável contendo as entradas (pares de chave-valor) do mapa fornecido.
//Cópia do mapa de pontuação de jogadores
Map<String, Integer> pontuacaoCopia = Map.copyOf(pontuacao);
System.out.println(pontuacaoCopia);
//saída: {Player_3=50, Player_2=124, Player_1=100}
Classe HashMap
É uma das implementações mais utilizadas da interface Map em Java, oferecendo uma combinação eficiente de performance, simplicidade e flexibilidade com as seguintes características:
- Alto desempenho: fornece desempenho para operações simples de GET e PUT.
- Permite null: aceita uma chave null e múltiplos valores null, o que não é possível em algumas outras implementações.
- Não ordenado: não mantém a ordem de inserção das chaves.
- É mutável: diferente dos mapas imutáveis, o HashMap permite adicionar, remover ou atualizar pares chave-valor.
construtor
Constrói um HashMap vazio. Para esse exemplo temos um mapa com chaves do tipo String e valores do tipo *Double, onde iremos armazenar temperaturas de cidades.
//Mapa para a temperatura das cidades
Map<String, Double> temperaturas = new HashMap<>();
put()
Insere um novo par de chave-valor associando o valor especificado à chave especificada nesse mapa.
temperaturas.put("São Paulo", 22.5);
temperaturas.put("Rio Grande do Sul", 9.0);
temperaturas.put("Pernambuco", 34.2);
temperaturas.put("Mato Grosso", 30.0);
System.out.println(temperaturas);
//saída: {Mato Grosso=30.0, Pernambuco=34.2, São Paulo=22.5, Rio Grande do Sul=9.0}
size()
Retorna o número de mapeamentos de chave-valor neste mapa.
var numeroMapeamentos = temperaturas.size();
System.out.println(numeroMapeamentos);
//saída: 4
values()
Retorna uma coleção(Collection) dos valores contidos no mapa.
var valoresMapeados = temperaturas.values();
System.out.println(valoresMapeados);
//saída: [30.0, 34.2, 22.5, 9.0]
keySet()
Retorna uma coleção(Set) das chaves contidas no mapa.
var chavesMapeadas = temperaturas.keySet();
System.out.println(chavesMapeadas);
//saída: [Mato Grosso, Pernambuco, São Paulo, Rio Grande do Sul]
containsKey()
Podemos verificar se uma determinada chave existe no mapa. O método containsKey() retorna verdadeiro (true) se o mapa possuir o mapeamento com a chave especificada.
var chaveExiste = temperaturas.containsKey("São Paulo");
System.out.println(chaveExiste);
//saída: true
containsValue()
Da mesma forma, podemos verificar se um determinado valor existe no mapa. O método containsValue() retorna verdadeiro (true) se o mapa possuir o mapeamento com o valor especificado.
var valorExiste = temperaturas.containsValue(23.9);
System.out.println(valorExiste);
//saída: false
get()
Para recuperar um valor mapeado utilizamos o método get(). Caso o valor especificado não for encontrado, o retorno será null.
var mapeamentoEncontrado = temperaturas.get("São Paulo");
System.out.println(mapeamentoEncontrado);
//saída: 22.5
var mapeamentoNaoEncontrado = temperaturas.get("Rio de Janeiro");
System.out.println(mapeamentoNaoEncontrado);
//saída: null
remove()
Para remover um mapeamento (par chave-valor), basta utilizar o método remove() especificando a chave do mapeamento.
temperaturas.remove("Pernambuco");
System.out.println(temperaturas);
//saída: {Mato Grosso=30.0, São Paulo=22.5, Rio Grande do Sul=9.0}
computeIfPresente()
Utilizado para atualizar um valor associado a uma chave, somente se essa chave já existir no mapa e não for null. É um método interessante quando você precisa atualizar condicionalmente um valor existente, evitando utilizar métodos como containsKey() + put() deixando o código mais limpo e conciso.
//Como Mato Grosso existe no mapa, somará 1.0 ao valor do mapeamento.
temperaturas.computeIfPresent("Mato Grosso", (chave, valor) -> valor + 1.0);
System.out.println(temperaturas.get("Mato Grosso"));
//saída: 31.0
computeIfAbsent()
Utilizado para adicionar um valor a uma chave no mapa somente se essa chave ainda não estiver presente (ou seja, não existir). Para casos onde o valor precisa ser calculado (sob demanda). É um método interessante, evitando utilizar métodos como containsKey() + put() deixando o código mais limpo e conciso.
//Nesse caso, como Rio de Janeiro não existe no mapa, será inserido.
temperaturas.computeIfAbsent("Rio de Janeiro", chave -> 39.4 + 1);
System.out.println(temperaturas.get("Rio de Janeiro"));
//saída: 40.4
putIfAbsent()
Muito parecido com o método computeIfAbsent(), utilizado para adicionar um valor a uma chave no mapa somente se essa chave ainda não estiver presente (ou seja, não existir). Para casos onde o valor já está pronto. É um método interessante, evitando utilizar métodos como containsKey() + put() deixando o código mais limpo e conciso.
temperaturas.putIfAbsent("Bahia", 37.6);
System.out.println(temperaturas.get("Bahia"));
//saída: 37.6
clear()
Remove todos os mapeamentos do mapa.
temperaturas.clear();
System.out.println(temperaturas);
//saída: {}
isEmpty()
Retorna verdadeiro (true) se o mapa estiver vazio. Ou seja, não contiver mapeamentos de chave-valor.
var mapeamentoVazio = temperaturas.isEmpty();
System.out.println(mapeamentoVazio);
//saída: true
Conclusão
Ao longo deste artigo, exploramos a interface Map em Java e vimos como ela é poderosa para representar estruturas de dados baseadas em chave e valor. Compreendemos desde sua definição até o uso prático de métodos essenciais como put, get, containsKey, computeIfPresent e computeIfAbsent.
Também conhecemos os mapas imutáveis com Map.of, Map.ofEntries e Map.copyOf, que oferecem alternativas seguras para situações onde não queremos permitir alterações após a criação.
Por fim, abordamos o HashMap, uma das implementações mais populares, graças à sua performance e simplicidade — sendo amplamente utilizado no dia a dia de quem desenvolve em Java.
Se você está começando agora ou reforçando conceitos, entender bem como usar Map é fundamental para escrever códigos mais limpos, eficientes e expressivos.
🔗 Repositório com os exemplos do artigo
Acesse o repositório com todos os exemplos prontos para rodar:
👉 https://github.com/LuizEduardoBilotta/demo—lebilotta-map