【发布时间】:2011-03-02 12:37:53
【问题描述】:
如果 LinkedHashMap 的时间复杂度和 HashMap 的复杂度一样,为什么我们需要 HashMap?与 Java 中的 HashMap 相比,LinkedHashMap 的额外开销是多少?
【问题讨论】:
标签: java hashmap complexity-theory linkedhashmap
如果 LinkedHashMap 的时间复杂度和 HashMap 的复杂度一样,为什么我们需要 HashMap?与 Java 中的 HashMap 相比,LinkedHashMap 的额外开销是多少?
【问题讨论】:
标签: java hashmap complexity-theory linkedhashmap
如果 LinkedHashMap 的时间复杂度和 HashMap 的复杂度一样,为什么还需要 HashMap?
您不应将复杂性与性能混为一谈。两种算法可以具有相同的复杂性,但其中一种算法的性能始终优于另一种。
记住f(N) is O(N)
的意思是:
limit(f(N), N -> infinity) <= C*N
其中C
是一个常数。复杂性并没有说明C
值的大小。对于两种不同的算法,常量C
很可能不同。
(请记住,大 O 复杂性与 N
变得非常大时的行为/性能有关。它不会告诉您较小的 N
值的行为/性能。)
话虽如此:
在等效用例中HashMap
和LinkedHashMap
操作之间的性能差异相对较小。
LinkedHashMap
使用更多内存。例如,Java 11 实现在每个映射条目中有两个额外的引用字段来表示之前/之后列表。在没有压缩 OOP 的 64 位平台上,额外开销是每个条目 16 个字节。
相对较小的性能和/或内存使用差异实际上对使用性能或内存至关重要的应用程序的人来说非常重要1。
1 - ...以及那些不必要地痴迷于这些事情的人。
【讨论】:
LinkedHashMap 在您需要知道 Map 中键的插入顺序时是一种有用的数据结构。一种合适的用例是实现 LRU 缓存。由于 LinkedHashMap 的顺序维护,数据结构比 HashMap 需要额外的内存。如果不需要插入顺序,则应始终使用 HashMap。
【讨论】:
HashMap
不维护插入顺序,因此不维护任何双向链表。
LinkedHashMap
最显着的特点是它维护了键值对的插入顺序。 LinkedHashMap
使用双向链表。
LinkedHashMap
的条目如下所示:
static class Entry<K, V> {
K key;
V value;
Entry<K,V> next;
Entry<K,V> before, after; //For maintaining insertion order
public Entry(K key, V value, Entry<K,V> next){
this.key = key;
this.value = value;
this.next = next;
}
}
通过使用 before 和 after - 我们跟踪 LinkedHashMap
中新添加的条目,这有助于我们维护插入顺序。
在参考之前的条目和
after 指的是LinkedHashMap
中的下一个条目。
图表及分步说明请参考http://www.javamadesoeasy.com/2015/02/linkedhashmap-custom-implementation.html
【讨论】:
HashMap 和 LinkedHashMap 的另一个主要区别是:LinkedHashMap 的迭代效率更高。
由于 LinkedHashMap 中的元素相互连接,因此迭代所需的时间与地图的大小成正比,而不管其容量如何。 但在 HashMap 的情况下;由于没有固定的顺序,因此对其进行迭代需要与其容量成正比的时间。
我已在我的blog 上提供了更多详细信息。
【讨论】:
LinkedHashMap 继承了 HashMap,这意味着它使用 HashMap 的现有实现将键和值存储在节点(条目对象)中。除此之外,它还存储了一个单独的双向链表实现,以维护输入键的插入顺序。
看起来像这样:
头节点节点1 节点2 节点3 节点4 头节点。
所以额外的重载是在这个双向链表中维护插入和删除。 好处是:保证迭代顺序是插入顺序,在HashMap中是没有的。
【讨论】:
【讨论】:
【讨论】:
iteration order = insertion order
是默认的。 插入顺序的可能替代方法是访问顺序。
LinkedHashMap 会占用更多内存。普通HashMap
中的每个条目都只有键和值。每个LinkedHashMap
条目都有这些引用和 对下一个和前一个条目的引用。还有一点点家务要做,虽然这通常无关紧要。
【讨论】: