为啥 ByteBuffers hashCodes 是一样的?
Posted
技术标签:
【中文标题】为啥 ByteBuffers hashCodes 是一样的?【英文标题】:why are ByteBuffers hashCodes the same?为什么 ByteBuffers hashCodes 是一样的? 【发布时间】:2012-06-18 19:42:13 【问题描述】:我有一个这样的类构造函数:
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 的内容。
【问题讨论】:
docs.oracle.com/javase/1.4.2/docs/api/java/nio/… -ByteBuffer.hashCode
取决于缓冲区中的剩余内容。
即使两个对象具有相同的hashCode
,这并不意味着它们的相似性或相等性。
@Erik 请不要参考旧文档,而是参考 Java 6 或 7。这是ByteBuffer 的实际文档
【参考方案1】:
来自 javadoc:
字节缓冲区的哈希码仅取决于其剩余元素;也就是说,在从 position() 到且包括在 limit() - 1 处的元素上。
因为缓冲区哈希码是依赖于内容的,所以不建议在哈希映射或类似数据结构中使用缓冲区作为键,除非知道它们的内容不会改变。
如果您没有填充ByteBuffers
,或者使用相同的东西填充它们,哈希码将是相同的。
【讨论】:
【参考方案2】:来自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
,因此哈希码始终相同。哈希码取决于缓冲区的内容,而不是用于表示它的物理对象。
【讨论】:
【参考方案3】:这是正确的行为。根据 ByteBuffer 文档:
当且仅当,两个字节缓冲区相等
它们具有相同的元素类型,
它们具有相同数量的剩余元素,并且
剩余元素的两个序列,独立于它们的起始位置,逐点相等。
字节缓冲区不等于任何其他类型的对象。
所以,假设 this.size() 总是返回相同的东西,你的缓冲区总是相等的。根据 hashCode 的通用合约,它们必须具有相同的哈希码。
您似乎正在尝试使用 hashCode 来确定对象身份 - 这不是一个好主意(因为 hashCode 和 == 如何交互)。如果您需要将类的实例彼此区分开来,并且需要比 == 运算符提供的更多内容,则必须找到其他方法来做到这一点。
【讨论】:
【参考方案4】:ByteBuffer.hashcode
让您计算包装字节[] 的哈希值。在这种情况下,新初始化的 byte[] 的内容对于每个字节都是 0。假设 ByteBuffer 内容相同,hashcode 相同。
【讨论】:
以上是关于为啥 ByteBuffers hashCodes 是一样的?的主要内容,如果未能解决你的问题,请参考以下文章
由于 Netty 中的 ByteBuffers 导致的内存泄漏