据我所知,两个不相等的对象可以具有相同的哈希码。在从HashMap java添加或检索时如何处理?
答案 0 :(得分:28)
它们将被添加到同一个存储桶中,equals()
将用于区分它们。
每个存储桶都可以包含具有相同哈希码的对象列表。
理论上,您可以为给定类的任何对象返回与哈希代码相同的整数,但这意味着您将失去哈希映射的所有性能优势,并且实际上会将对象存储在列表中。
答案 1 :(得分:7)
在HashMap中,键及其关联值存储在存储桶中的链接列表节点中,键基本上使用equals()方法而不是hashcode在hashmap中进行比较。
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
。答案 2 :(得分:1)
HashMap正在研究散列和索引的概念。 内部HashMap将值存储在节点数组中。 每个节点都表现为LinkedList。
链表的每个节点都有4个值:
public function createQuery($context = 'list')
{
/** @var \Doctrine\ORM\QueryBuilder|QueryBuilder $query */
$query = parent::createQuery($context);
$query
->addSelect($query->getRootAliases()[0])
->addSelect('collectionOrder')
;
$query
->leftJoin($query->getRootAliases()[0] . '.order', 'collectionOrder')
;
return $query;
}
int hash
K key
V value
HashMap内部结构:
在HashMap中插入值时,会生成Key的第一个哈希码,并根据某些算法计算索引。
因此,我们的值将使用下一个元素的哈希码,键,值和地址存储在特定索引中。
从HashMap中检索值时,第一个哈希码将生成然后索引(与插入时的方式相同)。在从索引获取值时,首先它将检查哈希码,如果哈希码匹配,那么只有它将使用equals方法从Node检查密钥。 如果密钥匹配,则只返回该值,否则将检查具有相同哈希码的下一个节点。
答案 3 :(得分:0)
在这种情况下,您可以使用IdentityHashMap,其中具有相同散列的不同对象根据其身份被视为不同。
答案 4 :(得分:0)
当两个不相等的对象具有相同的哈希值时,这会导致哈希表中的冲突,因为两个对象都希望位于同一个槽中(有时称为桶)。哈希算法必须解决此类冲突。回到我大学算法课程的褪色记忆中,我记得三种基本方法:
我认为Java哈希类使用第三种方法,但它们可能使用组合方法。良好哈希的关键是确保哈希表具有足够大的容量并编写好的哈希函数。只有与它所持有的对象一样多的存储桶的哈希表可能会有冲突。通常,您希望哈希表大约是它存储的对象数量的两倍。 Java的HashMap将根据需要增长,但如果需要,可以给它一个起始容量和负载因子。
哈希函数取决于程序员。您可以为所有对象返回0,但这意味着散列(存储和检索)将变为O(n)而不是O(1)...或者在非专业术语中,它将是狗慢。
参考:http://www.coderanch.com/t/540275/java/java/objects-hashcode-HashMap-retrieve-objects