【发布时间】:2018-08-05 21:31:32
【问题描述】:
我正在查看 Java 7 中 HashMap 的源代码,我看到 put 方法将检查是否已经存在任何条目,如果存在则它将用新值替换旧值价值。
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
所以,基本上这意味着给定键总是只有一个条目,我也通过调试看到了这一点,但如果我错了,请纠正我。
现在,既然给定键只有一个条目,为什么get 方法有一个 FOR 循环,因为它可以直接返回值?
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
我觉得上面的循环是不必要的。如果我错了,请帮助我理解。
【问题讨论】:
-
每个键一个条目,是的,但不是每个哈希一个条目。
-
wikipedia article on hash tables,尤其是关于单独链式冲突解决的部分很好地说明了值如何在链表内部存储。您需要遍历列表以达到正确的值,因为列表(存储桶)只能通过哈希码访问。
-
您的分析不完整:您忽略了
put方法也 有一个for循环。这应该有助于回答您的问题。 -
@DanielPryden 同意。最好的方法是尝试自己实现一个 - 或者将其作为学习工具的更简单实现。迟早,您会遇到
for循环修复的完全相同的问题,您就会知道原因。