2012-06-18 14 views
6

Tengo un constructor de la clase así:¿Por qué ByteBuffers hashCodes es el mismo?

public JavoImageCorrectedDataHeader() 
    { 
     ByteBuffer buffer = ByteBuffer.allocate(this.size()); 
     buffer.order(java.nio.ByteOrder.LITTLE_ENDIAN); 
     setByteBuffer(buffer, 0); 
     System.out.println("buffer.hasCode=" + buffer.hashCode()); 
    } 

En mis otras clases, crear muchas instancias de la clase anterior en diferentes lugares y tiempo mediante el uso

new JavoImageCorrectedDataHeader() 

Entonces, esperaba que se imprimirá diferentes hashCode para ellos. pero en realidad veo el mismo hashCode se imprima:

buffer.hasCode=1742602241 
buffer.hasCode=1742602241 
buffer.hasCode=1742602241 
buffer.hasCode=1742602241 
buffer.hasCode=1742602241 
buffer.hasCode=1742602241 
buffer.hasCode=1742602241 
buffer.hasCode=1742602241 
buffer.hasCode=1742602241 
buffer.hasCode=1742602241 
buffer.hasCode=1742602241 
buffer.hasCode=1742602241 
buffer.hasCode=1742602241 
buffer.hasCode=1742602241 
buffer.hasCode=1742602241 
buffer.hasCode=1742602241 
buffer.hasCode=1742602241 
buffer.hasCode=1742602241 
buffer.hasCode=1742602241 
buffer.hasCode=1742602241 

debo perder algo acerca de cómo usar la ByteBuffer.

+0

http://docs.oracle.com/javase/1.4.2/docs/api/java/nio/ByteBuffer.html#hashCode() - 'ByteBuffer.hashCode' depende del contenido restante en el búfer. – Erik

+0

Incluso si dos objetos tienen el mismo 'hashCode', eso no implica nada acerca de su similitud o igualdad. –

+0

@Erik, por favor, no consulte la documentación anterior, en lugar de Java 6 o 7. Esta es la documentación real de [ByteBuffer] (http://docs.oracle.com/javase/6/docs/api/java/nio/ ByteBuffer.html) –

Respuesta

10

Desde el javadoc:

El código hash de una memoria intermedia de bytes depende solamente de sus restantes elementos; es decir, sobre los elementos desde la posición() hasta, e incluyendo, el elemento en el límite() - 1.

Como los códigos hash del búfer dependen del contenido, no es aconsejable usar búferes como claves en los mapas hash o estructuras de datos similares a menos que se sepa que su contenido no cambiará.

Si no está rellenando el ByteBuffers, o los está poblando con las mismas cosas, los códigos hash serán idénticos.

2

ByteBuffer.hashcode le permite calcular un hash del byte envuelto []. En este caso, el contenido del byte recién inicializado [] es 0 para cada byte. Dado que el contenido de ByteBuffer es el mismo, el código hash es el mismo.

5

A partir del código fuente ByteBuffer.java:

public int hashCode() { 
    int hashCode = get(position()) + 31; 
    int multiplier = 1; 
    for (int i = position() + 1; i < limit(); ++i) { 
     multiplier *= 31; 
     hashCode += (get(i) + 30)*multiplier; 
    } 
    return hashCode; 
} 

Bajo su implementación actual, position() siempre devuelve 0 y por lo tanto, los hashcodes son siempre idénticos. El código hash depende del contenido del búfer, no del objeto físico que se utiliza para representarlo.

3

Este es el comportamiento correcto. Por la documentación ByteBuffer:

dos memorias intermedias de bytes son iguales si, y sólo si,

Ellos tienen el mismo tipo de elemento,

Ellos tienen el mismo número de elementos restantes, y

Las dos secuencias de elementos restantes, consideradas independientemente de sus posiciones iniciales, son puntuales iguales.

Un búfer de byte no es igual a ningún otro tipo de objeto.

Por lo tanto, suponiendo que this.size() siempre devuelve lo mismo, sus búferes siempre son iguales. Según el contrato general de hashCode, todos deben tener el mismo código hash.

Parece que está intentando usar hashCode para determinar la identidad del objeto; esta no es una buena idea (debido a cómo hashCode y == interactúan). Si necesita distinguir instancias de su clase entre sí, y necesita más de lo que le da el operador ==, tendrá que buscar otra forma de hacerlo.

Cuestiones relacionadas