简体   繁体   中英

why are ByteBuffers hashCodes the same?

I have a class constructor like this:

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 my other classes, I create many instances of above class in different locations and time by using

new JavoImageCorrectedDataHeader()

Then, I expected it will print out different hashCode for them. but I actually see the same hashCode is print out:

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

I must miss something about how to use the ByteBuffer.

From the javadoc:

The hash code of a byte buffer depends only upon its remaining elements; that is, upon the elements from position() up to, and including, the element at limit() - 1.

Because buffer hash codes are content-dependent, it is inadvisable to use buffers as keys in hash maps or similar data structures unless it is known that their contents will not change.

If you are not populating the ByteBuffers , or are populating them with the same things, the hash codes will be identical.

From the ByteBuffer.java source code:

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

Under your current implementation, position() always returns 0 and thus, the hashcodes are always identical. The hashcode is dependent on the content of the buffer, not on the physical object that is used to represent it.

This is the correct behavior. Per the ByteBuffer documentation:

Two byte buffers are equal if, and only if,

They have the same element type,

They have the same number of remaining elements, and

The two sequences of remaining elements, considered independently of their starting positions, are pointwise equal.

A byte buffer is not equal to any other type of object.

So, assuming that this.size() always returns the same thing, your buffers are always equal. Per the general contract of hashCode, they must therefore all have the same hash code.

You appear to be trying to use hashCode to determine object identity - this isn't a good idea (because of how hashCode and == interact). If you need to distinguish instances of your class from each other, and need more than what the == operator gives you, you'll have to find some other way to do it.

ByteBuffer.hashcode lets you calculate a hash of the wrapped byte[]. In this case, the content of the newly initialized byte[] is 0 for each byte. Given that the ByteBuffer content is the same, the hashcode is the same.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM