Classe HashSet do Java: Guia Completo de Operações, Métodos e Teoria de Conjuntos
Classe HashSet do Java
Explore a classe HashSet do Java — sua criação, métodos principais e operações práticas de conjunto — através de exemplos concisos.
A classe HashSet, parte do Java Collections Framework, implementa a interface Set e oferece armazenamento baseado em tabela hash.
Criando um HashSet
Primeiro, importe java.util.HashSet:
import java.util.HashSet;
Então crie um HashSet com capacidade específica e fator de carga:
HashSet<Integer> numeros = new HashSet<>(8, 0.75); // capacidade=8, loadFactor=0.75
Parâmetros:
- capacidade – contagem inicial de buckets (8 neste exemplo).
- fatorDeCarga – limite que dispara redimensionamento (0.75 significa redimensionar quando 75% cheio).
Usar padrões também é comum:
HashSet<Integer> numeros1 = new HashSet<>(); // capacidade=16, loadFactor=0.75
Métodos do HashSet
Abaixo estão os métodos mais frequentemente usados:
add(T elemento)– insere um único elemento.addAll(Collection<? extends T> c)– inserção em massa.remove(Object o)– deleta um elemento específico.removeAll(Collection<? extends Object> c)– limpa múltiplos elementos.contains(Object o)– verifica presença.size()– número de elementos.clear()– remove todas as entradas.clone()– cria uma cópia rasa.isEmpty()– testa se vazio.containsAll(Collection<? extends Object> c)– verificação de subconjunto.
Inserindo Elementos
Exemplo usando add e addAll:
import java.util.HashSet;
class Main {
public static void main(String[] args) {
HashSet<Integer> numeroPar = new HashSet<>();
numeroPar.add(2);
numeroPar.add(4);
numeroPar.add(6);
System.out.println("HashSet: " + numeroPar);
HashSet<Integer> numeros = new HashSet<>();
numeros.addAll(numeroPar);
numeros.add(5);
System.out.println("Novo HashSet: " + numeros);
}
}
Saída
HashSet: [2, 4, 6] Novo HashSet: [2, 4, 5, 6]
Acessando Elementos
Itere com Iterator:
import java.util.HashSet;
import java.util.Iterator;
class Main {
public static void main(String[] args) {
HashSet<Integer> numeros = new HashSet<>();
numeros.add(2);
numeros.add(5);
numeros.add(6);
System.out.println("HashSet: " + numeros);
Iterator<Integer> iterar = numeros.iterator();
System.out.print("HashSet usando Iterator: ");
while(iterar.hasNext()) {
System.out.print(iterar.next() + ", ");
}
}
}
Saída
HashSet: [2, 5, 6] HashSet usando Iterator: 2, 5, 6,
Removendo Elementos
Remoção única e limpeza do conjunto:
import java.util.HashSet;
class Main {
public static void main(String[] args) {
HashSet<Integer> numeros = new HashSet<>();
numeros.add(2);
numeros.add(5);
numeros.add(6);
System.out.println("HashSet: " + numeros);
boolean removido = numeros.remove(5);
System.out.println("5 foi removido? " + removido);
boolean limpo = numeros.removeAll(numeros);
System.out.println("Todos elementos removidos? " + limpo);
}
}
Saída
HashSet: [2, 5, 6] 5 foi removido? true Todos elementos removidos? true
Operações de Conjunto
Os métodos em massa do HashSet suportam operações clássicas de teoria de conjuntos.
União
import java.util.HashSet;
class Main {
public static void main(String[] args) {
HashSet<Integer> numerosPares = new HashSet<>();
numerosPares.add(2);
numerosPares.add(4);
HashSet<Integer> numeros = new HashSet<>();
numeros.add(1);
numeros.add(3);
numeros.addAll(numerosPares);
System.out.println("União é: " + numeros);
}
}
Saída
União é: [1, 2, 3, 4]
Interseção
import java.util.HashSet;
class Main {
public static void main(String[] args) {
HashSet<Integer> numerosPrimos = new HashSet<>();
numerosPrimos.add(2);
numerosPrimos.add(3);
HashSet<Integer> numerosPares = new HashSet<>();
numerosPares.add(2);
numerosPares.add(4);
numerosPares.retainAll(numerosPrimos);
System.out.println("Interseção é: " + numerosPares);
}
}
Saída
Interseção é: [2]
Diferença
import java.util.HashSet;
class Main {
public static void main(String[] args) {
HashSet<Integer> numerosPrimos = new HashSet<>();
numerosPrimos.add(2);
numerosPrimos.add(3);
numerosPrimos.add(5);
HashSet<Integer> numerosImpares = new HashSet<>();
numerosImpares.add(1);
numerosImpares.add(3);
numerosImpares.add(5);
numerosPrimos.removeAll(numerosImpares);
System.out.println("Diferença: " + numerosPrimos);
}
}
Saída
Diferença: [2]
Verificação de Subconjunto
import java.util.HashSet;
class Main {
public static void main(String[] args) {
HashSet<Integer> numeros = new HashSet<>();
numeros.add(1);
numeros.add(2);
numeros.add(3);
numeros.add(4);
HashSet<Integer> numerosPrimos = new HashSet<>();
numerosPrimos.add(2);
numerosPrimos.add(3);
boolean eSubconjunto = numeros.containsAll(numerosPrimos);
System.out.println("numerosPrimos é subconjunto de numeros? " + eSubconjunto);
}
}
Saída
numerosPrimos é subconjunto de numeros? true
Métodos Adicionais
| Método | Descrição |
|---|---|
clone() | Cria uma cópia rasa do conjunto. |
contains() | Verifica se um elemento existe. |
isEmpty() | Retorna true se o conjunto está vazio. |
size() | Número de elementos no conjunto. |
clear() | Remove todos os elementos. |
Para uma lista completa, consulte a documentação oficial do Java.
Por Que Usar HashSet?
Quando acesso aleatório é requerido, HashSet oferece desempenho O(1) graças ao seu backing de tabela hash. O hashCode() de cada elemento garante unicidade, prevenindo duplicatas. No entanto, HashSet não é thread-safe; sincronização externa é necessária para uso concorrente.
Nota: Como HashSet não é sincronizado, múltiplas threads modificando-o concorrentemente podem corromper a estrutura de dados.
Java
- Entendendo a Palavra-chave final em Java: Variáveis, Métodos e Classes
- Operador instanceof em Java: Guia Completo
- Entendendo Classes Aninhadas Estáticas em Java: Uso, Diferenças e Exemplos
- Dominando Classes Internas Anônimas em Java: Definição, Sintaxe e Exemplos Práticos
- Padrão Singleton em Java Explicado: Como Implementar e Usar com Segurança
- Dominando Reflection em Java: Inspecionando Classes, Métodos e Campos em Tempo de Execução
- Dominando Algoritmos de Coleção Java: Ordenação, Embaralhamento e Mais
- Dominando Java ObjectOutputStream: Serialização, Métodos e Exemplos Práticos
- Dominando Java Generics – Construindo Código Reutilizável e Type-Safe
- Dominando Operações de Arquivo em Java com java.io – Criação, Leitura, Escrita e Exclusão