6

我有一个这样的类构造函数:

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

在我的其他课程中,我通过使用在不同的位置和时间创建了上述课程的许多实例

new JavoImageCorrectedDataHeader()

然后,我希望它会为它们打印出不同的 hashCode。但我实际上看到打印出相同的hashCode :

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

我必须错过一些关于如何使用 ByteBuffer 的内容。

4

4 回答 4

11

从javadoc:

字节缓冲区的哈希码仅取决于其剩余元素;也就是说,在从 position() 到且包括在 limit() - 1 处的元素上。

因为缓冲区哈希码是依赖于内容的,所以不建议使用缓冲区作为哈希映射或类似数据结构中的键,除非知道它们的内容不会改变。

如果您没有填充ByteBuffers,或者使用相同的东西填充它们,则哈希码将是相同的。

于 2012-06-18T19:47:06.987 回答
5

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

在您当前的实现下,position() 总是返回0,因此哈希码总是相同的。哈希码取决于缓冲区的内容,而不是用于表示它的物理对象。

于 2012-06-18T19:49:10.823 回答
3

这是正确的行为。根据 ByteBuffer 文档:

当且仅当,两个字节缓冲区相等

它们具有相同的元素类型,

它们具有相同数量的剩余元素,并且

剩余元素的两个序列,独立于它们的起始位置考虑,是逐点相等的。

字节缓冲区不等于任何其他类型的对象。

所以,假设 this.size() 总是返回相同的东西,你的缓冲区总是相等的。根据 hashCode 的一般合同,因此它们都必须具有相同的哈希码。

您似乎正在尝试使用 hashCode 来确定对象身份 - 这不是一个好主意(因为 hashCode 和 == 如何交互)。如果您需要将类的实例彼此区分开来,并且需要比 == 运算符提供的更多内容,则必须找到其他方法来做到这一点。

于 2012-06-18T19:50:28.320 回答
2

ByteBuffer.hashcode让您计算包装字节 [] 的哈希值。在这种情况下,新初始化的 byte[] 的内容对于每个字节都是 0。假设 ByteBuffer 内容相同,则哈希码相同。

于 2012-06-18T19:48:41.743 回答