class temp {
int id;
public int getId() {
return id;
}
temp(int id) {
this.id = id;
}
public void setId(int id) {
this.id = id;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
temp other = (temp) obj;
if (id != other.id)
return false;
return true;
}
}
public class testClass {
public static void main(String[] args) {
temp t1 = new temp(1);
temp t2 = new temp(1);
System.out.println(t1.equals(t2));
Set<temp> tempList = new HashSet<temp>(2);
tempList.add(t1);
tempList.add(t2);
System.out.println(tempList);
}
El programa agrega los dos elementos al conjunto. Me sorprendió al principio porque al agregar métodos para establecer, se invoca el método igual.HashSet permite la inserción de elementos duplicados si hashCode() no se reemplaza
Pero luego me hizo caso omiso el método hashCode:
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
return result;
}
Y entonces no agregó. Esto es sorprendente ya que el método Javadoc de Set y add() dice que solo verifica() mientras se agrega en el Conjunto.
Y este es el Javadoc para add():
/**
* Adds the specified element to this set if it is not already present.
* More formally, adds the specified element <tt>e</tt> to this set if
* this set contains no element <tt>e2</tt> such that
* <tt>(e==null ? e2==null : e.equals(e2))</tt>.
* If this set already contains the element, the call leaves the set
* unchanged and returns <tt>false</tt>.
*
* @param e element to be added to this set
* @return <tt>true</tt> if this set did not already contain the specified
* element
*/
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
Entonces me di cuenta de que el HashSet se implementa como un HashMap y en el mapa, el código hash del objeto se utiliza como clave. Por lo tanto, les está tratando con diferentes claves si no reemplaza hashCode.
¿No debería estar esto en la documentación del método add() o de HashSet?
El motivo completo por el que existe la función hashCode() es para colecciones basadas en hash. ¿Cómo debe una colección "saber" qué función hash usar si no la define? –
Descubrí que el método equals() de la temperatura de clase nunca se llama en este caso (intentado sysout), por lo que la JVM invoca el valor predeterminado igual() si no tenemos implementado hashCode() para cumplir el contrato de JVM especificación. Interesante !!!!!!! –
Llama solo 'igual' si los' hashCode() 'son los mismos. No llama al valor predeterminado igual si lo reemplaza. –