Java 在发生冲突的情况下,从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。它

假设我有一个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。它链接到元素_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中下一个元素的引用。我很抱歉一次又一次地问,但我只是完全陷入了困惑之中。非常感谢。这确实是一个很大的帮助。