Como sabemos, um conjunto é uma coleção bem definida de objetos distintos. Cada membro de um conjunto é chamado de elemento do conjunto. Em outras palavras, podemos dizer que um conjunto nunca conterá elementos duplicados . Mas como na interface java Set implementadas classes como HashSet , LinkedHashSet , TreeSet etc. alcançam essa exclusividade. Neste post, discutiremos a verdade oculta por trás dessa singularidade.

Como o HashSet funciona internamente em Java?

Como Set / HashSet funciona internamente em Java
Vamos entender isso com um exemplo. Vejamos a saída do programa a seguir, que tenta adicionar elementos duplicados em um HashSet.

// Java program to demonstrate
// internal working of HashSet
  
import java.util.HashSet;
  
class Test
{    
    public static void main(String args[]) 
    {
        // creating a HashSet
        HashSet hs = new HashSet();
          
        // adding elements to hashset
        // using add() method
        boolean b1 = hs.add("Geeks");
        boolean b2 = hs.add("GeeksforGeeks");
          
        // adding duplicate element
        boolean b3 = hs.add("Geeks");
          
        // printing b1, b2, b3
        System.out.println("b1 = "+b1);
        System.out.println("b2 = "+b2);
        System.out.println("b3 = "+b3);
          
        // printing all elements of hashset
        System.out.println(hs);
              
    }
}

Saída:

b1 = true
b2 = true
b3 = false
[GeeksforGeeks, Geeks]

Agora, pela saída, fica claro que quando tentamos adicionar um elemento duplicado a um conjunto usando o método add() , ele retorna falso , e o elemento não é adicionado ao hashset, pois já está presente. Agora vem a questão, como o método add() verifica se o conjunto já contém o elemento especificado ou não. Ficará mais claro se examinarmos mais de perto o método add() e o construtor padrão na classe HashSet.

// predefined HashSet class
public class HashSet
{
    // A HashMap object 
    private transient HashMap map;

    // A Dummy value(PRESENT) to associate with an Object in the Map
    private static final Object PRESENT = new Object();
    
    // default constructor of HashSet class
    // It creates a HashMap by calling 
    // default constructor of HashMap class
    public HashSet() {
        map = new HashMap<>();
    }

    // add method 
    // it calls put() method on map object
    // and then compares it's return value with null
    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
 
    // Other methods in Hash Set
}

Agora, como você pode ver que sempre que criamos um HashSet, ele cria internamente um HashMap e se inserirmos um elemento neste HashSet usando o método add() , ele realmente chama o método put() no objeto HashMap criado internamente com o elemento que você especificou como é o objeto chave e constante chamado “PRESENT” como seu valor. Portanto, podemos dizer que um conjunto atinge a exclusividade internamente por meio do HashMap . Agora toda a história gira em torno de como um método HashMap e put() funciona internamente .

Como sabemos em um HashMap, cada chave é única e quando chamamos o método put (Key, Value) , ele retorna o valor anterior associado à chave, ou nulo se não houver mapeamento para a chave. Portanto, no método add() , verificamos o valor de retorno do método map.put (chave, valor) com valor nulo .

  1. Se map.put (chave, valor) retornar nulo , a instrução “map.put (e, PRESENTE) == nulo” retornará verdadeiro e o elemento será adicionado ao HashSet (internamente HashMap).
  2. Se map.put (chave, valor) retorna o valor antigo da chave, então a instrução “map.put (e, PRESENT) == null” retornará falso e o elemento não será adicionado ao HashSet (internamente HashMap).

Como LinkedHashSet estende HashSet, ele chama internamente os construtores de HashSet usando super() . Da mesma forma, criar um objeto da classe TreeSet internamente cria o objeto Navigable Map como mapa de apoio.

Artigo relacionado: Como o HashMap funciona internamente em Java.

Este artigo é uma contribuição de Gaurav Miglani . Se você gosta de GeeksforGeeks e gostaria de contribuir, você também pode escrever um artigo usando contribute.geeksforgeeks.org ou enviar o seu artigo para contribute@geeksforgeeks.org. Veja o seu artigo na página principal do GeeksforGeeks e ajude outros Geeks.

Escreva comentários se encontrar algo incorreto ou se quiser compartilhar mais informações sobre o tópico discutido acima.