LinkedHashMap
中的删除是否需要线性时间。由于我们需要从保持插入顺序的链表中删除密钥,因此需要O(n)
时间。常规HashMap
删除需要一段时间。
答案 0 :(得分:8)
根据Javadocs,它不是:
此类提供所有可选的
Map
操作,并允许null元素。与HashMap
类似,它为基本操作(add
,contains
和remove
)提供常量时间性能,假设散列函数分散元素适当的水桶之间。由于维护链表的额外费用,性能可能略低于HashMap的性能,但有一个例外:对LinkedHashMap
的集合视图进行迭代需要与 size <成比例的时间/ em>的地图,无论其容量如何。HashMap
上的迭代可能更昂贵,需要时间与容量成比例。
LinkedHashMap
未覆盖HashMap#remove(Object key)
方法。后者从表中删除与键对应的条目,并在已删除的条目上调用recordRemoval()
方法,该方法调整已删除条目的上一个和下一个的链接。列表中没有迭代,以便删除某个索引处的节点。
答案 1 :(得分:2)
LinkedHasMap使用一个子类HashMap.Entry的Entry,因此成本更高但仍然是常量。
每次在HashMap中删除一个条目时,都会调用recordRemoval(HashMap m)方法。它在HashMap.Entry中的实现是空的但是LinkedHasMap。条目只是从列表中删除条目):
/**
* Removes this entry from the linked list.
*/
private void remove() {
before.after = after;
after.before = before;
}
序列如下:
删除HashMap调用中的实现removeEntryForKey(HashMap:line551)
public V remove(Object key) {
Entry<K,V> e = removeEntryForKey(key);
return (e == null ? null : e.value);
}
HashMap中的removeEntryForKey调用entry.recordRemoval(this)(HashMap:line560)
final Entry<K,V> removeEntryForKey(Object key) {
[...]
while (e != null) {
Entry<K,V> next = e.next;
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k)))) {
[...]
e.recordRemoval(this);
return e;
}
prev = e;
e = next;
}
return e;
}
LinkedHasMap.Entry中的recordRemoval实现调用上面的remove方法,即O(1)(LinkedHashMap:line357)
void recordRemoval(HashMap<K,V> m) {
remove();
}
HashMap的来源: http://hg.openjdk.java.net/jdk7/jdk7/jdk/file/9b8c96f96a0f/src/share/classes/java/util/HashMap.java
LinkedHashMap的来源: http://hg.openjdk.java.net/jdk7/jdk7/jdk/file/9b8c96f96a0f/src/share/classes/java/util/LinkedHashMap.java