HashSet exactly how it works [duplicated]

1

Suppose I have this main:

import java.util.*;

public class Main {

        public static void main(String[] args) {
            HashSet<Persona> conjuntoPersonas= new HashSet<>();
            Persona p1 = new Persona("Jose", "1");
            Persona p2 = new Persona("Ivan", "2");
            Persona p3 = new Persona("Alex", "2");
            System.out.println(conjuntoPersonas.add(p1));
            System.out.println(conjuntoPersonas.add(p2));
            System.out.println(conjuntoPersonas.add(p3));
            System.out.println(conjuntoPersonas.size());
    }
}

And this class Person:

public class Persona {
    private String nombre;
    private String dni;

    public Persona(String nombre, String dni) {
        this.nombre = nombre;
        this.dni = dni;
    }

    @Override
    public boolean equals(Object o) {
        Persona persona = (Persona) o;
        return this.dni.equals(persona.getDni());
    }



    public String getDni() {
        return dni;
    }

}

I understood that when I run it I should print:

true  // lo añade al conjunto
true  // lo añade al conjunto
false // no lo añade al conjunto por que entiende que esta repetido 
2     // imprime dos por que el tercer elemento no lo añade

However, I get

true
true
true
3

And in the debugger I see that if I add it even if it is repeated. Can someone help me understand why I do not get the desired behavior ???

    
asked by lujoselu 06.12.2017 в 12:26
source

1 answer

3

To check that 2 objects are equal, 2 conditions have to be fulfilled:

  • That the method% co_of% returne true
  • If the method equals returns true, then it is understood that the method equals(object) also returns true.
  • Let's test your code and check if both are correct:

      public static void main(String[] args) {
            HashSet<Persona> conjuntoPersonas= new HashSet<>();
            Persona p1 = new Persona("Jose", "1");
            Persona p2 = new Persona("Ivan", "2");
            Persona p3 = new Persona("Alex", "2");
    
    
            System.out.println(conjuntoPersonas.add(p2)); // true
            System.out.println(conjuntoPersonas.add(p3)); // true
            System.out.println(p2.hashCode()); // 366712642
            System.out.println(p3.hashCode()); // 1829164700
    
        }
    

    As notes, the method hashCode() returns true in both cases, but the method add() returns different results so hasCode() understands that they are different objects although HashSet returne equals .

    You have to write the method true of the class hashCode() and return the hashCode of the object with which you are comparing, which in this case would be Persona :

    public static class Persona {
        private String nombre;
        private String dni;
    
        public Persona(String nombre, String dni) {
            this.nombre = nombre;
            this.dni = dni;
        }
    
        @Override
        public boolean equals(Object o) {
            Persona persona = (Persona) o;
            return this.dni.equals(persona.getDni());
        }
    
        // sobre escribimos el metodo hashCode() y returnanos el hashCode() del dni ya que es el
        // campo principal para comprar
        @Override
        public int hashCode() {
            return getDni().hashCode();
        }
    
        public String getDni() {
            return dni;
        }
    
    }
    

    If we try now it will give us the desired result:

      public static void main(String[] args) {
            HashSet<Persona> conjuntoPersonas= new HashSet<>();
            Persona p1 = new Persona("Jose", "1");
            Persona p2 = new Persona("Ivan", "2");
            Persona p3 = new Persona("Alex", "2");
    
    
            System.out.println(conjuntoPersonas.add(p2)); // true
            System.out.println(conjuntoPersonas.add(p3)); // false
            System.out.println(p2.hashCode()); // 50
            System.out.println(p3.hashCode()); // 50
    
        }
    

    Now, we must be careful when writing about this method. If you want more information, take a look at the question Equals and HashCode? Java that explains the topic very well.

        
    answered by 06.12.2017 / 13:58
    source