2009-09-24 27 views
17

Tengo una pregunta rápida sobre las colecciones TreeSet y los métodos hashCode. Tengo un TreeSet y le agrego objetos, antes de agregar un objeto, verifico si existe en el TreeSet usando el método contains.Java - TreeSet y hashCode()

tengo 2 objetos distintos, cada uno de los cuales producen un hashCode distinta usando mi implementación del método hashCode, ejemplo siguiente:

public int hashCode() 
{ 
    int hash = 7; 
    hash = hash * 31 + anAttribute.hashCode(); 
    hash = hash * 31 + anotherAttribute.hashCode(); 
    hash = hash * 31 + yetAnotherAttribute.hashCode(); 
    return hash; 
} 

Los hashcodes para una ejecución particular son: 76126352 y 76126353 (los objetos sólo difieren por un dígito en un atributo).

El método contains devuelve true para estos objetos, aunque los hashCodes sean diferentes. ¿Alguna idea de por qué? Esto es realmente confuso y la ayuda realmente sería apreciada.

Respuesta

34

TreeSet no usa hashCode en absoluto. Utiliza compareTo o el Comparador que pasó al constructor. Esto es usado por métodos como contiene para encontrar objetos en el conjunto.

Así que la respuesta a su pregunta es que su método compareTo o su Comparador están definidos de manera que los dos objetos en cuestión se consideran iguales.

De los javadocs:

una instancia TreeSet realiza todas las comparaciones elemento utilizando su compareTo (o comparar) del método, por lo que dos elementos que se consideran iguales por este método son, desde el punto de vista de el conjunto , igual.

+0

También utiliza el método equals, por lo que es importante que equals y Comparator/compareTo sean coherentes. –

+6

No según los javadocs no. – sepp2k

+2

"Esto es así porque la interfaz Set se define en términos de la operación equals, pero una instancia TreeSet realiza todas las comparaciones de elementos utilizando su método compareTo (o comparar) ..." (desde http://java.sun.com/ javase/6/docs/api/java/util/TreeSet.html) – Dirk

3

De Java Doc:

Si dos objetos son iguales de acuerdo con los método equals (Object), entonces una llamada al método hashCode en cada uno de los dos objetos debe producir el mismo resultado entero.

Medios: los objetos que utiliza para el hashing no son iguales.

+1

Eso supone que hashCode e iguales se han definido de una manera que no rompe ese contrato. – sepp2k

+2

@ sepp2k Este * es * el 'contrato general para 'hashCode()''. Es por eso que usa la palabra "debe". – EJP

0

Debe leer el capítulo 3 de Joshua Bloch "Effective Java". Explica el contrato igual y cómo anular correctamente iguales, código hash y compareTo.

+0

Incluso está disponible en línea: http://java.sun.com/developer/Books/effectivejava/Chapter3.pdf – gustafc

+0

Estaba listo para votar el comentario de gustafc, pero el enlace ahora está roto :( –

+0

Ve a comprar el libro. todavía está afuera. – duffymo

0

No necesita comprobar si está contenido, porque la inserción() básicamente realiza la misma operación (es decir, busca en la posición correcta) en su camino hacia el punto de inserción. Si el objeto no se puede insertar (es decir, el objeto ya está contenido), insert devuelve falso.

+0

Ese es un ejemplo (como la mayoría de las clases de Colección) de una API muy limpia y concisa. – helpermethod

Cuestiones relacionadas