我有一个像这样的类构造函数:
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。
答案 0 :(得分:11)
来自javadoc:
字节缓冲区的哈希码仅取决于其余的元素;也就是说,来自position()的元素直到并包括limit() - 1处的元素。
由于缓冲区哈希码与内容有关,因此不建议将缓冲区用作哈希映射或类似数据结构中的键,除非知道它们的内容不会发生变化。
如果您没有填充ByteBuffers
,或者使用相同的东西填充它们,则哈希码将是相同的。
答案 1 :(得分: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
,因此,哈希码始终相同。哈希码取决于缓冲区的内容,而不是用于表示它的物理对象。
答案 2 :(得分:3)
这是正确的行为。根据ByteBuffer文档:
当且仅当
时,两个字节的缓冲区相等它们具有相同的元素类型,
它们具有相同数量的剩余元素,
与其起始位置无关地考虑的两个剩余元素序列在点上是相等的。
字节缓冲区不等于任何其他类型的对象。
因此,假设this.size()总是返回相同的东西,那么缓冲区总是相等的。根据hashCode的一般契约,它们必须都具有相同的哈希码。
您似乎正在尝试使用hashCode来确定对象标识 - 这不是一个好主意(因为hashCode和==如何交互)。如果你需要区分你的类的实例,并且需要比==运算符给你的更多,你必须找到一些其他方法来实现它。
答案 3 :(得分:2)
ByteBuffer.hashcode
允许您计算包装字节[]的哈希值。在这种情况下,每个字节的新初始化byte []的内容为0。鉴于ByteBuffer内容相同,哈希码是相同的。