2012-06-18 14 views
6

Ho un costruttore della classe come questo:perché i codici hash di ByteBuffers sono uguali?

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

Nelle mie altre classi, ho creare molti casi di classe superiore in diverse posizioni e tempo utilizzando

new JavoImageCorrectedDataHeader() 

Poi, mi aspettavo che stamperà fuori hashCode diverso per loro. ma io in realtà vedo la stessa hashCode è stampare:

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 

devo perdere qualcosa su come utilizzare il ByteBuffer.

+0

http://docs.oracle.com/javase/1.4.2/docs/api/java/nio/ByteBuffer.html#hashCode() - 'ByteBuffer.hashCode' dipende dal contenuto rimanente nel buffer. – Erik

+0

Anche se due oggetti hanno lo stesso 'hashCode', questo non implica nulla sulla loro somiglianza o uguaglianza. –

+0

@Erik per favore non fare riferimento alla vecchia documentazione, invece di Java 6 o 7. Questa è la documentazione effettiva di [ByteBuffer] (http://docs.oracle.com/javase/6/docs/api/java/nio/ ByteBuffer.html) –

risposta

10

Dal javadoc:

Il codice hash di un buffer di byte dipende solo restanti elementi; cioè, sugli elementi da position() fino a, e incluso, l'elemento al limite() - 1.

Poiché i codici hash del buffer dipendono dal contenuto, è sconsigliabile utilizzare i buffer come chiavi nelle mappe hash o strutture di dati simili a meno che non si sappia che il loro contenuto non cambierà.

Se non si popola il ByteBuffers o se si popolano con le stesse cose, i codici di hash saranno identici.

2

ByteBuffer.hashcode consente di calcolare un hash del byte spostato []. In questo caso, il contenuto del byte appena inizializzato [] è 0 per ogni byte. Dato che il contenuto ByteBuffer è lo stesso, l'hashcode è lo stesso.

5

Dal codice sorgente di 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; 
} 

Sotto l'implementazione corrente, position() restituisce sempre 0 e, quindi, i codici hash sono sempre identici. L'hashcode dipende dal contenuto del buffer, non dall'oggetto fisico che viene utilizzato per rappresentarlo.

3

Questo è il comportamento corretto. Per la documentazione ByteBuffer:

due buffer byte sono uguali se e solo se,

Essi hanno lo stesso tipo di elemento,

Essi hanno lo stesso numero di elementi rimanenti e

Le due sequenze di elementi rimanenti, considerate indipendentemente dalle loro posizioni di partenza, sono uguali in senso inverso.

Un buffer di byte non è uguale a nessun altro tipo di oggetto.

Quindi, supponendo che this.size() restituisce sempre la stessa cosa, i vostri tamponi sono sempre uguali. Per il contratto generale di hashCode, devono quindi avere tutti lo stesso codice hash.

Sembra che stiate cercando di usare hashCode per determinare l'identità dell'oggetto - questa non è una buona idea (a causa di come hashCode e == interagiscono). Se devi distinguere tra loro le istanze della tua classe e hai bisogno di più di quello che ti dà l'operatore ==, dovrai trovare un altro modo per farlo.