Java WeakHashMap – Entendendo, Uso e Diferenças Principais
Java WeakHashMap
Um guia abrangente do WeakHashMap do Java, cobrindo sua criação, diferenças principais do HashMap, exemplos práticos e métodos essenciais.
A classe WeakHashMap faz parte do Java Collections Framework e implementa a interface Map. Ela se comporta como uma tabela hash normal, mas armazena chaves como referências fracas, permitindo que sejam recuperadas pelo garbage collector quando não mais em uso.
Nota: Chaves em um WeakHashMap são embrulhadas em objetos WeakReference.
Uma referência fraca pode ser garbage-collected se o programa não mantiver mais uma referência forte para o objeto-chave.
Criando um WeakHashMap
Primeiro, importe java.util.WeakHashMap:
import java.util.WeakHashMap;
Então instancie, opcionalmente especificando capacidade inicial e fator de carga:
// WeakHashMap com capacidade 8 e fator de carga 0.6
WeakHashMap<Chave, Valor> numeros = new WeakHashMap<>(8, 0.6);
Parâmetros:
- capacidade – o número de entradas que o mapa pode conter antes de redimensionar. Padrão é 16.
- fatorDeCarga – o limite no qual o mapa expande. Padrão é 0.75.
Quando nenhum parâmetro é fornecido, os valores padrão se aplicam:
WeakHashMap<Chave, Valor> numeros = new WeakHashMap<>();
HashMap vs. WeakHashMap
Embora ambos implementem Map, a distinção chave está na força da referência:
- HashMap – chaves são referências fortes; entradas persistem até remoção explícita.
- WeakHashMap – chaves são referências fracas; entradas desaparecem quando a chave não é mais alcançável.
Exemplo demonstrando o comportamento:
import java.util.WeakHashMap;
class Main {
public static void main(String[] args) {
WeakHashMap<String, Integer> numeros = new WeakHashMap<>();
String dois = new String("Dois");
Integer doisValor = 2;
String quatro = new String("Quatro");
Integer quatroValor = 4;
numeros.put(dois, doisValor);
numeros.put(quatro, quatroValor);
System.out.println("WeakHashMap: " + numeros);
// Anular a referência para a chave
dois = null;
System.gc();
System.out.println("WeakHashMap após GC: " + numeros);
}
}
Saída:
WeakHashMap: {Quatro=4, Dois=2} WeakHashMap após GC: {Quatro=4}
A entrada para "Dois" desaparece porque sua chave não é mais fortemente alcançável. Em contraste, um HashMap reteria a entrada:
import java.util.HashMap;
class Main {
public static void main(String[] args) {
HashMap<String, Integer> numeros = new HashMap<>();
String dois = new String("Dois");
Integer doisValor = 2;
String quatro = new String("Quatro");
Integer quatroValor = 4;
numeros.put(dois, doisValor);
numeros.put(quatro, quatroValor);
System.out.println("HashMap: " + numeros);
dois = null;
System.gc();
System.out.println("HashMap após GC: " + numeros);
}
}
Saída:
HashMap: {Quatro=4, Dois=2} HashMap após GC: {Quatro=4, Dois=2}
Assim, WeakHashMap é ideal quando você quer que o mapa libere automaticamente memória ligada a chaves não usadas.
Convertendo de Outro Mapa
Instancie um WeakHashMap a partir de um mapa existente para copiar suas entradas:
import java.util.HashMap;
import java.util.WeakHashMap;
class Main {
public static void main(String[] args) {
HashMap<String, Integer> numerosPares = new HashMap<>();
String dois = new String("Dois");
numerosPares.put(dois, 2);
System.out.println("HashMap: " + numerosPares);
WeakHashMap<String, Integer> numeros = new WeakHashMap<>(numerosPares);
System.out.println("WeakHashMap: " + numeros);
}
}
Saída:
HashMap: {Dois=2} WeakHashMap: {Dois=2}
Métodos Principais do WeakHashMap
Abaixo está uma seleção das operações mais usadas.
Inserindo Entradas
put(chave, valor)– adiciona um mapeamento.putAll(mapa)– mescla outro mapa.putIfAbsent(chave, valor)– insere apenas se a chave estiver ausente.
Exemplo:
import java.util.WeakHashMap;
class Main {
public static void main(String[] args) {
WeakHashMap<String, Integer> numerosPares = new WeakHashMap<>();
numerosPares.put(new String("Dois"), 2);
numerosPares.putIfAbsent(new String("Quatro"), 4);
System.out.println("Números pares: " + numerosPares);
WeakHashMap<String, Integer> numeros = new WeakHashMap<>();
numeros.put(new String("Um"), 1);
numeros.putAll(numerosPares);
System.out.println("Todos números: " + numeros);
}
}
Saída:
Números pares: {Quatro=4, Dois=2} Todos números: {Dois=2, Quatro=4, Um=1}
Acessando Entradas
Recupere dados via:
get(chave)– retorna o valor ounullse ausente.getOrDefault(chave, padrão)– retorna um padrão quando a chave está faltando.entrySet(),keySet(),values()– itere sobre entradas, chaves ou valores.
Exemplo:
import java.util.WeakHashMap;
class Main {
public static void main(String[] args) {
WeakHashMap<String, Integer> numeros = new WeakHashMap<>();
numeros.put(new String("Um"), 1);
numeros.put(new String("Dois"), 2);
System.out.println("Mapa: " + numeros);
System.out.println("Conjunto de entradas: " + numeros.entrySet());
System.out.println("Chaves: " + numeros.keySet());
System.out.println("Valores: " + numeros.values());
System.out.println("Get Dois: " + numeros.get("Dois"));
System.out.println("GetOrDefault Quatro: " + numeros.getOrDefault("Quatro", 4));
}
}
Saída:
Mapa: {Dois=2, Um=1} Conjunto de entradas: [Dois=2, Um=1] Chaves: [Dois, Um] Valores: [1, 2] Get Dois: 2 GetOrDefault Quatro: 4
Removendo Entradas
remove(chave)– remove e retorna o valor.remove(chave, valor)– remove apenas se o mapeamento atual corresponder ao valor fornecido.clear()– esvazia o mapa.containsKey(chave),containsValue(valor),size(),isEmpty()
Exemplo:
import java.util.WeakHashMap;
class Main {
public static void main(String[] args) {
WeakHashMap<String, Integer> numeros = new WeakHashMap<>();
numeros.put(new String("Um"), 1);
numeros.put(new String("Dois"), 2);
System.out.println("Mapa: " + numeros);
int removido = numeros.remove("Dois");
System.out.println("Valor removido: " + removido);
boolean removidoSe = numeros.remove("Um", 3);
System.out.println("Removido {Um=3}? " + removidoSe);
System.out.println("Após remoção: " + numeros);
}
}
Saída:
Mapa: {Dois=2, Um=1} Valor removido: 2 Removido {Um=3}? false Após remoção: {Um=1}
Utilitários Adicionais
| Método | Descrição |
|---|---|
clear() | Deleta todas as entradas. |
containsKey(chave) | Verifica se a chave existe. |
containsValue(valor) | Verifica se um valor está presente. |
size() | Retorna o número de entradas. |
isEmpty() | Retorna true se o mapa não tem entradas. |
Para um mergulho mais profundo, consulte a documentação oficial do Java WeakHashMap.
Java
- Dominando Operadores Java: Tipos, Sintaxe e Exemplos Práticos
- Comentários em Java: Tipos, Uso e Boas Práticas
- Dominando o Loop for Aprimorado em Java: Sintaxe, Exemplos e Boas Práticas
- Dominando Strings em Java: Criação, Métodos e Boas Práticas
- Dominando Interfaces em Java: Conceitos, Implementação e Boas Práticas
- Dominando Classes Internas Anônimas em Java: Definição, Sintaxe e Exemplos Práticos
- Dominando Try-With-Resources em Java: Gerenciamento Automático de Recursos Explicado
- Anotações em Java Explicadas: Tipos, Posicionamento e Exemplos Práticos
- Asserções em Java: Guia Prático para Detectar Bugs e Garantir Confiabilidade do Código
- Entendendo o Java Vector: Uso, Recursos e Comparação com ArrayList