2010-06-02 19 views
8

Tengo una clase, "Acumulador", que implementa el método CompareTo comparable, y estoy tratando de poner estos objetos en un HashSet.Java HashSet está permitiendo engaños; problema con comparable?

Cuando agrego() a la HashSet, no veo ninguna actividad en mi método compareTo en el depurador, independientemente de donde hice mis puntos de interrupción. Además, cuando termino con el add() s, veo varios duplicados dentro del conjunto.

¿Qué soy yo para atornillar, aquí; ¿Por qué no se compara y, por lo tanto, permite a los engañados?

Gracias,
IVR Avenger

Respuesta

15

qué estoy metiendo la pata, aquí?

HashSet se basa en hashCode(), no en compareTo(). Puede confundirlo con TreeSet. En ambos casos, asegúrese de implementar también equals() de una manera que sea consistente con el otro método.

10

que necesita para implementar correctamente hashCode() y equals().

Debe anular hashCode y devolver un número basado en los valores de su clase, de modo que dos objetos iguales tengan el mismo código hash.

+0

sin iguales, sería totalmente inválido. – Justin

1

HashSet usa hashCode y es igual. TreeSet usa la interfaz Comparable. Nota: si decide anular el hashcode o el igual, siempre debe anular el otro.

+1

Solo tiene que anular hashCode si se reemplaza equals (la definición es igualdad ha cambiado). A la inversa no es necesariamente cierto. Es perfectamente legal cambiar hashCode para devolver 1 y dejar iguales solo. –

2

Cuando hashCode devolver valores diferentes para 2 objetos, entonces igual no se utiliza. Por cierto, compareTo no tiene nada que ver con el hash colecciones :) pero colecciones ordenadas

2

Sus objetos son Comparable, y probablemente ha implementado equals() también, pero HashSets trato con los hashes de objetos, y las probabilidades son que no ha implementado hashCode() (o su aplicación de hashCode() no devuelve el mismo hash de dos objetos que son (a.equals(b) == true).

4

HashSet usa los métodos y hashCode()equals() para evitar duplicados se agreguen. en primer lugar, se pone el código hash del objeto que desea Luego, encuentra el cubo correspondiente para t Sombree el código hash e itera a través de cada objeto en ese depósito, utilizando el método equals() para ver si ya existen objetos idénticos en el conjunto.

¡Su depurador no se está rompiendo en compareTo() porque nunca se usa con HashSet!

Las reglas son:

  1. Si dos objetos son iguales, entonces sus códigos hash deben ser iguales.

  2. Pero si dos objetos códigos hash son iguales, entonces esto no significa los objetos son iguales!Podría ser que los dos objetos tienen el mismo hash.

1

Cuando cada vez que crea un objeto de la clase Acumulador que se necesita nuevo espacio en JVM y devuelve única hashCode cada vez que añada un objeto en hashset. No depende del valor del objeto porque no ha anulado método hashCode() por lo que llamará Objeto clase método hashCode() que devolverá el hashCode exclusivo con cada objeto creado en su programa.

Solución:

Anulación hashCode() yiguales() método y aplicar su lógica dependiendo de las propiedades de su clase. Asegúrese de leer iguales y contrato de código hash

http://www.ibm.com/developerworks/java/library/j-jtp05273/index.html

+0

el enlace proporcionado es muy útil y para bininer personas como yo es muy útil. –

2

Algo que la gente tiende a ignorar que se traducen en un gran error. Al definir el método igual siempre tome el parámetro como clase de objeto y luego converse el objeto a su clase deseada. Por ejemplo

public bolean equals(Object aSong){ 
    if(!(aSoneg instanceof Song)){ 
     return false; 
    } 
    Song s=(Song) aSong; 
    return getTitle().equals(s.getTitle()); 
    } 

Si U llegue escribir la canción ASONG en lugar de objetos ASONG método de sus iguales no será llamado.

Espero que esto ayude

Cuestiones relacionadas