HashMap, HashSet e Hashtable em Java

Hiten Kanwar 12 outubro 2023
  1. Java HashMap
  2. Java Hashtable
  3. Java HashSet
HashMap, HashSet e Hashtable em Java

A interface Collection do Java nos fornece várias interfaces e classes para implementar uma variedade de estruturas de dados e algoritmos.

Este tutorial irá discutir HashMap, HashSet e Hashtable em Java.

Primeiro, vamos entender o que são tabelas hash em geral.

Podemos usar tabelas hash para armazenar elementos em um padrão de par de valores-chave, o que significa que cada chave tem um valor associado a ela. Chave é um valor exclusivo usado para indexar os valores. Valor são os dados relacionados à chave correspondente.

A estrutura de dados da tabela hash segue o conceito de hashing, onde um novo índice é processado usando as chaves. O elemento que corresponde a essa chave é então armazenado no índice. Este é o conceito de Hashing.

Seja h(x) a função hash e k uma chave, então h(k) fornecerá um novo índice para armazenar os elementos ligados a k.

Java HashMap

O HashMap é uma classe do framework de coleções Java que nos fornece a estrutura de dados da tabela hash. Ele armazena os elementos como um par de valores-chave, onde as chaves são os identificadores exclusivos emparelhados a um valor específico em um mapa. A classe HashMap implementa a interface Map, que estende ainda mais a interface Collections.

O HashMap não está sincronizado, o que significa que não é seguro para threads. Podemos acessá-lo usando vários threads e modificá-lo ao mesmo tempo. Pode ser feito externamente seguro para thread.

Outra característica do HashMap é que ele pode conter uma chave nula ou pares de valores.

Por exemplo,

import java.util.HashMap;

public class Main {
  public static void main(String[] args) {
    HashMap<String, Integer> h = new HashMap<>();
    h.put("One", 1);
    h.put("Two", 2);
    h.put("Three", 3);
    System.out.println(h);
  }
}

Produção:

HashMap: {One=1, Two=2, Three=3}

Java Hashtable

A classe Hashtable de Java implementa a estrutura de dados da tabela hash. Semelhante a HashMap, ele também armazena os elementos como um par de valores-chave. Mas difere de um HashMap porque está sincronizado. Ele armazena o par de valores-chave na tabela de hash. Ele implementa a interface do Mapa.

Primeiro, na Hashtable, especificamos o objeto como a chave, com seu valor como um par. A chave é então hash, e então usamos o código hash resultante é usado como um índice para o valor armazenado na tabela.

Por isso, o problema associado a Hashtable é que a sincronização de cada chamada de método não é relativamente insignificante. Não é necessário todas as vezes. Assim, para superar esse problema, os autores do framework de coleções criaram uma nova classe chamada HashMap (que também esclarece que mapeia os elementos) que não está sincronizada.

Se alguém não quiser usar a sincronização em nível de método, pode pular o Hashtable e usar Collections.synchronizedMap() que transforma um mapa em um mapa sincronizado. Alternativamente, podemos usar ConcurrentHashMap, que de acordo com sua documentação, oferece a mesma funcionalidade que Hashtable, mas tem melhor desempenho e algumas funcionalidades adicionais.

Por exemplo,

import java.io.*;
import java.util.*;

public class Main {
  public static void main(String args[]) {
    Hashtable<Integer, String> h = new Hashtable<>();
    h.put(1, "one");
    h.put(2, "two");
    h.put(3, "three");
    System.out.println(h);
  }
}

Produção:

{3=three, 2=two, 1=one}

Java HashSet

O HashSet é uma classe do framework de coleções Java que nos fornece a implementação da estrutura de dados da tabela hash (assim como HashMap). Ainda assim, ele implementa a interface Set (ao contrário de HashMap), que estende ainda mais a interface Collections. Isso geralmente é usado quando não precisamos mapear chaves para pares de valores.

O HashSet difere do Hashtable de uma forma que HashSet não pode conter valores duplicados. Os pares de valores-chave são exclusivos. Em termos de funcionalidade, HashSet não tem nada em comum com o HashMap, mas passa a usar um HashMap internamente para implementar a interface Set.

Por exemplo,

import java.util.HashSet;

public class Main {
  public static void main(String[] args) {
    HashSet<Integer> h = new HashSet<>();
    h.add(5);
    h.add(10);
    h.add(15);
    System.out.println(h);
  }
}

Produção:

[5, 10, 15]

Artigo relacionado - Java HashMap

Artigo relacionado - Java Hashtable