我理解两个不相等的对象可以有相同的哈希码。在 Java 的 HashMap 中,当添加或检索时,这将如何处理?
它们将被添加到同一个桶中,并使用equals()
方法来区分它们。每个桶可以包含具有相同哈希码的对象列表。
理论上,你可以为给定类的任何对象返回相同的整数作为哈希码,但这意味着你失去了哈希映射的所有性能优势,实际上将在列表中存储对象。
在HashMap中,键和它们关联的值被存储在桶(bucket)中的链表节点中,并且在hashmap中使用equals()方法而不是hashcode()方法对键进行比较。
hm.put("a","aValue"); // Suppose hashcode created for key "a" is 209
hm.put("b","bValue"); // Here hashcode created for key "b" is 209 as well.
a.equals(b)
返回true
,则bValue
将替换aValue
并返回bValue
。a.equals(b)
返回false
,则在桶列表中将创建另一个节点,因此当调用get("b")
时,您将获得bValue
,因为a.equals(b)
为false
。当两个不相等的对象具有相同的哈希值时,这会在哈希表中引起冲突,因为这两个对象都想在同一个插槽(有时称为桶)中。哈希算法必须解决这种冲突。回忆起我大学算法课程的模糊记忆,我记得有三种基本方法:
我认为Java哈希类使用第三种方法,但它们可能会使用组合方法。好的哈希关键在于确保哈希表具有足够大的容量并编写良好的哈希函数。只有与其持有的对象一样多的桶的哈希表可能会发生冲突。通常,您希望哈希表的大小约为存储的对象数量的两倍。Java的HashMap将根据需要增长,但如果需要,您可以给它一个起始容量和负载因子。
哈希函数取决于程序员。您可以为所有对象返回0,但这意味着哈希(存储和检索)将变为O(n),而不是O(1)...或者用通俗的话说,它将非常慢。
参考资料:http://www.coderanch.com/t/540275/java/java/objects-hashcode-HashMap-retrieve-objects
在这种情况下,您可以使用IdentityHashMap,在这里具有相同哈希的不同对象根据其身份被视为不同。
n >= 0
,所有new Long(n * 0x100000001L)
都具有哈希码0。 - Peter Lawrey