2012-06-18 10 views
6

Ich habe eine Klasse Konstruktor wie folgt aus:Warum sind ByteBuffers hashCodes gleich?

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()); 
    } 

In meinen anderen Klassen schaffe ich viele Fälle von oben Klasse an verschiedenen Orten und Zeit durch die Verwendung

new JavoImageCorrectedDataHeader() 

Dann erwartete ich es gedruckt wird aus verschiedenen hashCode für sie. aber ich sehe eigentlich das gleiche hashCode wird ausdrucken:

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 

ich etwas vermissen müssen, wie die ByteBuffer zu verwenden.

+0

http://docs.oracle.com/javase/1.4.2/docs/api/java/nio/ByteBuffer.html#hashCode() - 'ByteBuffer.hashCode' ist abhängig vom verbleibenden Inhalt im Puffer. – Erik

+0

Auch wenn zwei Objekte denselben 'hashCode' haben, bedeutet das nichts über ihre Ähnlichkeit oder Gleichheit. –

+0

@Erik beziehen Sie sich bitte nicht auf alte Dokumentation, sondern auf Java 6 oder 7. Dies ist die eigentliche Dokumentation von [ByteBuffer] (http://docs.oracle.com/javase/6/docs/api/java/nio/ ByteBuffer.html) –

Antwort

10

Vom Javadoc-:

Der Hash-Code eines Puffers Byte nur auf seinen übrigen Elemente abhängt; das heißt, auf die Elemente von Position() bis einschließlich und das Element bei limit() - 1.

Da Puffer Hash-Codes inhaltsabhängig sind, ist es nicht ratsam, Puffer als Schlüssel in Hash-Maps zu verwenden ähnliche Datenstrukturen, es sei denn, es ist bekannt, dass sich ihr Inhalt nicht ändert.

Wenn Sie die ByteBuffers nicht füllen oder sie mit denselben Dingen füllen, sind die Hashcodes identisch.

2

ByteBuffer.hashcode können Sie einen Hash des eingepackten Bytes [] berechnen. In diesem Fall ist der Inhalt des neu initialisierten Bytes [] für jedes Byte 0. Da der ByteBuffer-Inhalt derselbe ist, ist der Hashcode identisch.

5

Vom ByteBuffer.java Quellcode:

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; 
} 

Unter Ihrer aktuellen Implementierung gibt position() immer 0 und damit die Hashcodes sind immer identisch. Der Hashcode hängt vom Inhalt des Puffers ab, nicht vom physischen Objekt, das für die Darstellung verwendet wird.

3

Dies ist das korrekte Verhalten. Per der ByteBuffer Dokumentation:

Zwei-Byte-Puffer sind gleich, wenn, und nur wenn

Sie den gleichen Elementtyp haben,

Sie die gleiche Anzahl von übrigen Elemente haben, und

Die zwei Sequenzen der verbleibenden Elemente, die unabhängig von ihren Startpositionen betrachtet werden, sind punktweise gleich.

Ein Byte-Puffer entspricht keinem anderen Objekttyp.

Also vorausgesetzt, dass this.size() immer das Gleiche zurückgibt, sind Ihre Puffer immer gleich. Gemäß dem allgemeinen Vertrag von hashCode müssen sie daher alle denselben Hash-Code haben.

Sie scheinen zu versuchen, HashCode zu verwenden, um Objektidentität zu bestimmen - das ist keine gute Idee (wegen wie hashCode und == interagieren). Wenn Sie Instanzen Ihrer Klasse voneinander unterscheiden müssen und mehr benötigen als der Operator ==, müssen Sie einen anderen Weg finden, dies zu tun.