如果同一个类的两个对象在Java中具有相同的hashCode,那么它们将如何存储在HashMap
/ HashTable
中?哈希码和内存地址的实际架构是什么。 hashCode在内存中的位置是什么?
示例:有一个班级A
。在创建对象a1
和a2
时,它们将代表一些内存地址,但我每次都会覆盖哈希码。当我读到一篇文章时,我发现hashcode函数从内存地址生成一个哈希码。这意味着如果哈希码相同,则内存地址将相同。请清除我的怀疑。
public class A {
@Override
public int hashCode() {
return 1;
}
public static void main(String args[]) {
A a1 = new A();
A a2 = new A();
System.out.println(a1.hashCode());
System.out.println(a2.hashCode());
}
}
答案 0 :(得分:4)
没有两个对象(同时存在)可以拥有相同的内存地址。
他们可以具有相同的哈希码,尽管hashCode
实现试图避免这种情况。并且hashCode
的默认实现不必基于对象的内存地址(尽管可以)。
因此,如果两个对象具有相同的哈希码,则不能假设它们具有相同的内存地址。实际上,如果两个变量引用不同的对象(即将它们与==
进行比较,则返回false
),它们肯定会不具有相同的地址。
您阅读的有关基于内存地址的哈希码的文章是指hashCode
类中Object
方法的默认实现。如果覆盖子类中的hashCode
,则不再使用该默认实现。您的return 1
与内存地址无关。
答案 1 :(得分:0)
hashCode()
的默认对象版本基于内存地址。当您覆盖hashCode()
方法并返回不同的值时,它不会更改Object的内存地址。也不会返回一个恒定的1个中断HashMap
,但它会严重影响性能。
答案 2 :(得分:0)
的System.out.println(A1 == A2); 结果是错误的。
答案 3 :(得分:0)
请注意,由于对象通常根据其内容/值而不是对象标识来定义自己的hashcode和equals实现,因此hashcode与对象的地址无法可靠地相关。
标识哈希码 - 它也是java.lang.Object提供的默认哈希码实现 - 可能与对象地址相关,也可能不相关,具体取决于此JRE的垃圾收集器如何管理内存。 / p>
答案 4 :(得分:0)
哈希码和内存地址是两回事。 Hashcode用于识别存储器中的存储桶位置以存储密钥。但是具有相同哈希码的两个不相等的对象将驻留在同一个存储桶中但位于不同的存储器地址。
它们如何存储在HashMap / HashTable中?Hashcode不会驻留在任何地方的内存中。
任何散列集合都使用散列桶架构来决定存储对象的位置。这有助于快速检索对象。这是一种保存机制:
具有不同hashcode和non equal的对象(equals()
在两个对象上返回false):将保存在不同的散列桶中
具有不同哈希码且相等的对象:将保存在同一个哈希桶中,但保存在链表中
具有相同哈希码且相等的对象:保存后将相互覆盖
哈希码和内存地址的实际架构是什么。
hashCode在内存中的位置是什么?
当您尝试在散列集合中放置/检索元素时,始终会计算它。而hashcode方法提供了逻辑。
答案 5 :(得分:0)
我认为问题的根源是理解哈希值和内存位置之间的关系。 散列图/表使用数组来存储键和值。 从hash(key)函数获得的值用于确定数组中的索引。 如果你在本机方面再深一步,内存地址将是(数组+索引的第一个元素的内存地址)。在此内存位置,将存储实际对象的地址。
正如其他人已经回答的那样,如果两个对象具有相同的哈希值,那么这些对象将位于同一个桶中。意思是,在数组的相同索引值处。但是,在这种情况下为了避免碰撞,数组的每个元素都可以链接列表。因此,具有相同散列值的对象将添加到链接列表中。
答案 6 :(得分:-2)
如果两个对象具有相同的哈希码并且属于同一个类 - 如果两个对象都添加到Hashtable / HashMap,则第二个将替换第一个。