Java 在发生冲突的情况下,从LinkedHashMap检索元素的时间复杂度是多少?
假设我有一个LinkedHashMap对象,它只有8个编号为0到7的bucket。 现在我想添加元素。我添加了7个元素,结果如下: 1) 元素_1:桶号2。这将成为LinkedHashMap维护的链接列表的开始,以维护插入顺序。Java 在发生冲突的情况下,从LinkedHashMap检索元素的时间复杂度是多少?,java,collections,hashmap,linkedhashmap,Java,Collections,Hashmap,Linkedhashmap,假设我有一个LinkedHashMap对象,它只有8个编号为0到7的bucket。 现在我想添加元素。我添加了7个元素,结果如下: 1) 元素_1:桶号2。这将成为LinkedHashMap维护的链接列表的开始,以维护插入顺序。 1) 元素2:桶号3。这链接到元素_1 2) 要素3:铲斗编号1。这是链接到元素_2的 3) 元素4:桶号4。这是链接到Elemetn_3的 4) 元素_5:桶号5。这链接到元素_4 5) 要素6:铲斗编号3。此链接到元素_5(已发生碰撞) 6) 要素7:铲斗编号3。它
1) 元素2:桶号3。这链接到元素_1
2) 要素3:铲斗编号1。这是链接到元素_2的
3) 元素4:桶号4。这是链接到Elemetn_3的
4) 元素_5:桶号5。这链接到元素_4
5) 要素6:铲斗编号3。此链接到元素_5(已发生碰撞)
6) 要素7:铲斗编号3。它链接到元素_6(再次是碰撞) 现在假设我想要检索元素_7。这个元素的散列给了我桶号3。现在桶号3中的元素是元素2,元素6,元素7
那么下面两个的遍历顺序是什么:
a) 要素2->要素3->要素4->要素5->要素6->要素7.
或
b) 元素2->元素6->元素7 我认为答案应该是(a),因为LinkedHashMap维护一个链表来维护插入顺序。因此,如果顺序为(b),则表示特定元素正在存储两个引用,一个用于插入顺序中的下一个元素,另一个用于同一存储桶中的下一个元素 如果答案是(b),特定元素如何决定访问哪一个,即从两个参考中选择哪一个 用例场景是假设的,它可能与以下事实无关:元素的数量小于桶的数量,冲突的可能性更小。 回答时请牢记上述情景。
提前感谢。LinkedHashMap扩展了HashMap,因此链接与
get
无关,因此,在添加链接时,他们不应该让LinkedHashMap在get
上的效率降低,因为get不需要该链接。LinkedHashMap扩展了HashMap,其get
方法调用HashMap的getEntry
方法。HashMap的实现将每个bucket存储在一个单独的数组中,因此它不需要在整个数据集上循环,只需要在该bucket中的数据上循环。采用Oracle JDK 7:
final Entry<K,V> getEntry(Object key) {
int hash = (key == null) ? 0 : hash(key.hashCode());
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 != null && key.equals(k))))
return e;
}
return null;
}
final Entry getEntry(对象键){
int hash=(key==null)?0:hash(key.hashCode());
for(条目e=表[indexFor(hash,table.length)];
e!=null;
e=e.next){
对象k;
如果(e.hash==hash&&
((k=e.key)==key | |(key!=null&&key.equals(k)))
返回e;
}
返回null;
}
编辑
e.next
在HashMap.Entry
中定义,并且位于同一个bucket中,而e.after
和e.before
在LinkedHasMap.Entry
中定义,它们可以位于不同的bucket中。似乎插入顺序链表与按键查找项目的成本完全无关?换句话说,查找的成本应该与HashMap
的成本相同。如果结果是一个错误,那将非常奇怪(而且毫无意义)。这将只是一个链接列表!如果你有7个元素,你通常会有16个桶。但这个例子仍然有效。我同意这个结论,但我不能说我觉得推理链完全令人信服。是的,我确实注意到了这个实现。但正如我所说,在常规HashMap中,一个特定的条目(Map.entry对象)存储下一个Map.entry对象的引用(在同一个bucket中),但对于LinkedHashMap,该引用将是下一个插入的元素的引用。因此,为了迭代同一个bucket中的元素,特定元素是否存储了两个引用,一个用于下一个插入的元素,另一个用于同一个bucket中的下一个元素?如果是,它如何决定选择哪个参考?LinkedHashMap只提供附加链接;bucket链接仍然存在,这是出于必要的类外继承。是的,我确实注意到了这个实现。但正如我所说,在常规HashMap中,一个特定的条目(Map.entry对象)存储下一个Map.entry对象的引用(在同一个bucket中),但对于LinkedHashMap,该引用将是下一个插入的元素的引用。因此,为了迭代同一个bucket中的元素,特定元素是否存储了两个引用,一个用于下一个插入的元素,另一个用于同一个bucket中的下一个元素?如果是,它如何决定选择哪个引用?请参阅我的编辑:LinkedHashMap.Entry
扩展HashMap.Entry
,并在之前添加一个,在之后添加一个字段,这些字段是映射中的下一个和上一个节点(可能位于不同的存储桶中),但在调用get
时,使用的是Map.Entry
中的next
字段,它位于同一个bucket中。嗨,Assylias,我想你肯定是对的,因为只有Map才有意义。但为了交叉澄清,有两个引用:字段“after”存储插入顺序引用,“next”存储对同一bucket中下一个元素的引用。我很抱歉一次又一次地问,但我只是完全陷入了困惑之中。非常感谢。这确实是一个很大的帮助。