我读过一本书,它hashCode()
显示了一个内存区域,它有助于(例如HashSets
)在内存中定位适当的对象。但是,如果我们不能直接在 Java 中操作内存,那怎么可能呢?没有指针,除此之外,对象被创建并从一个地方移动到另一个地方,而开发人员对此一无所知。
我读到这种认识hashCode() {return 42;}
是可怕的和可怕的,但是如果我们不能指示 VM 将我们的对象放在哪里,那有什么区别呢?
问题是:hashCode()
如果我们不能操纵记忆,那么深层次的目的是什么?
我在一本书中读到 hashCode() 显示了一个内存区域,它有助于(例如 HashSets)在内存中定位适当的对象。
不,这完全是对hashCode
. 它用于以有效的方式找到可能相等的对象。它与对象在内存中的位置无关。
这个想法是,如果你有类似 a 的东西HashMap
,你想在查找时快速找到匹配的键。因此,您首先检查请求的键的哈希码,然后您可以使用该哈希码真正有效地找到映射中的所有键。然后,您可以检查每个(并且只有那些)候选键与请求的键是否相等。
有关更多信息,请参阅有关哈希表的 Wikipedia 文章。
我喜欢Jon Skeet 的回答(+1),但它需要知道哈希表是如何工作的。哈希表是一种数据结构,基本上是一个存储桶数组,它使用键的哈希码来决定将该条目插入哪个存储桶。这样将来检索该键上的任何内容的调用就不必筛选整个存储在hashtable中的事物列表,hashtable可以计算出key的hashcode,然后直接去匹配的bucket中查找。哈希码必须是可以快速计算的东西,并且您希望它是唯一的,但如果不是,那不是灾难,除非在最坏的情况下(您的return 42;
),这很糟糕,因为一切都以相同的方式结束桶,你又回来筛选一切。
Object#hashCode 的默认值可能基于诸如内存位置之类的东西,只是因为它是一种方便的随机数,但是由于在内存管理期间对象被分流,所以该值被缓存并且没有人关心。由不同对象(如 String 或 BigDecimal)创建的哈希码肯定与内存无关。它只是一个快速生成的数字,您希望它经常是独一无二的。
哈希码只是一个“值”。它与“您将它放在内存中的位置”无关,而“MyClass obj = new MyClass()”与“obj”在内存中的位置无关。
那么Java hashCode()到底是什么?
这是关于这个主题的一个很好的讨论:
K&B 说 hashcode() 合约是:
如果两个对象根据 equals(Object) 方法相等,则对两个对象中的每一个调用 hashCode() 方法必须产生相同的整数结果。
如果两个对象根据equals(Object)方法不相等,则不需要hashcode()。
如果在两个对象上调用 hashcode() 产生不同的整数结果,那么根据 equals(Object),它们必须是不相等的。
哈希码是一个接受对象并输出数值的函数。如果对象不变,则对象的哈希码始终相同。
像哈希图这样需要存储对象的函数,将使用哈希码对其内部数组的大小取模来选择存储对象的“内存位置”(即数组位置)。
在某些情况下可能会发生冲突(两个对象最终具有相同的哈希码,当然,这需要仔细解决)。有关详细信息,我建议阅读 wikipedia hashmap entry
HashCode 是对象的加密,通过该加密,java 知道例如集合中的两个对象是相同还是不同。(以排序集为例)
我建议你阅读这篇文章。
是的,它与内存地址无关,尽管它通常是通过转换对象的内部地址来实现的。在Object 的 hashCode()方法中找到的以下语句清楚地表明实现并非强制执行此操作。
在合理可行的情况下,由 Object 类定义的 hashCode 方法确实为不同的对象返回不同的整数。(这通常通过将对象的内部地址转换为整数来实现,但 JavaTM 编程语言不需要这种实现技术。
该hashCode()
函数接受一个对象并输出一个数值,该数值不必是唯一的。如果对象不变,则对象的哈希码始终相同。
hashCode() 返回的值是对象的哈希码,即对象的十六进制内存地址。
根据定义,如果两个对象相等,则它们的哈希码也必须相等。如果重写 equals() 方法,就会改变两个对象相等的方式,并且 Object 的 hashCode() 实现不再有效。因此,如果你重写 equals() 方法,你也必须重写 hashCode() 方法。
有关更多信息,请查看这篇Java 哈希码文章。