HashMap,LinkedHashMap 和 TreeMap 之间的区别

Map m1 = new HashMap();
m1.put("map", "HashMap");
m1.put("schildt", "java2");
m1.put("mathew", "Hyden");
m1.put("schildt", "java2s");
print(m1.keySet()); 
print(m1.values()); 

SortedMap sm = new TreeMap();
sm.put("map", "TreeMap");
sm.put("schildt", "java2");
sm.put("mathew", "Hyden");
sm.put("schildt", "java2s");
print(sm.keySet()); 
print(sm.values());

LinkedHashMap lm = new LinkedHashMap();
lm.put("map", "LinkedHashMap");
lm.put("schildt", "java2");
lm.put("mathew", "Hyden");
lm.put("schildt", "java2s");
print(lm.keySet()); 
print(lm.values());

答案

╔══════════════╦═════════════════════╦═══════════════════╦═════════════════════╗
║   Property   ║       HashMap       ║      TreeMap      ║     LinkedHashMap   ║
╠══════════════╬═════════════════════╬═══════════════════╬═════════════════════╣
║ Iteration    ║  no guarantee order ║ sorted according  ║                     ║
║   Order      ║ will remain constant║ to the natural    ║    insertion-order  ║
║              ║      over time      ║    ordering       ║                     ║
╠══════════════╬═════════════════════╬═══════════════════╬═════════════════════╣
║  Get/put     ║                     ║                   ║                     ║
║   remove     ║         O(1)        ║      O(log(n))    ║         O(1)        ║
║ containsKey  ║                     ║                   ║                     ║
╠══════════════╬═════════════════════╬═══════════════════╬═════════════════════╣
║              ║                     ║   NavigableMap    ║                     ║
║  Interfaces  ║         Map         ║       Map         ║         Map         ║
║              ║                     ║    SortedMap      ║                     ║
╠══════════════╬═════════════════════╬═══════════════════╬═════════════════════╣
║              ║                     ║                   ║                     ║
║     Null     ║       allowed       ║    only values    ║       allowed       ║
║ values/keys  ║                     ║                   ║                     ║
╠══════════════╬═════════════════════╩═══════════════════╩═════════════════════╣
║              ║   Fail-fast behavior of an iterator cannot be guaranteed      ║
║   Fail-fast  ║ impossible to make any hard guarantees in the presence of     ║
║   behavior   ║           unsynchronized concurrent modification              ║
╠══════════════╬═════════════════════╦═══════════════════╦═════════════════════╣
║              ║                     ║                   ║                     ║
║Implementation║      buckets        ║   Red-Black Tree  ║    double-linked    ║
║              ║                     ║                   ║       buckets       ║
╠══════════════╬═════════════════════╩═══════════════════╩═════════════════════╣
║      Is      ║                                                               ║
║ synchronized ║              implementation is not synchronized               ║
╚══════════════╩═══════════════════════════════════════════════════════════════╝

所有这三个类都实现Map接口,并提供大多数相同的功能。最重要的区别是通过条目进行迭代的顺序:

  • HashMap绝对不保证迭代顺序。添加新元素时,它甚至可以(并将)完全改变。
  • TreeMap将根据键的compareTo()方法(或外部提供的Comparator )根据键的 “自然顺序” 进行迭代。此外,它实现了SortedMap接口,该接口包含依赖于此排序顺序的方法。
  • LinkedHashMap将按照将条目放入地图的顺序进行迭代

“哈希表”是基于哈希的映射的通用名称。在 Java API 的上下文中, Hashtable是 Java 1.1 在集合框架存在之前的过时类。不再使用它,因为它的 API 充满了重复功能的过时方法,并且其方法是同步的(这会降低性能,并且通常是无用的)。使用ConcurrentHashMap而不是 Hashtable。

这三个代表从唯一键到值的映射,因此实现了Map接口。

  1. HashMap 是基于键哈希的映射。它支持 O(1)get / put 操作。密钥必须具有hashCode()equals()一致实现,此hashCode()才能起作用。

  2. LinkedHashMap 与 HashMap 非常相似,但是它增加了添加(或访问)项目的顺序的意识,因此迭代顺序与插入顺序(或访问顺序,取决于构造参数)相同。

  3. TreeMap 是基于树的映射。其放置 / 获取操作花费 O(log n)时间。它要求项目具有可比较或比较器的某种比较机制。迭代顺序由此机制确定。

在下图中查看每个类在类层次结构中的位置( 较大的一个 )。 TreeMap 实现SortedMapNavigableMapHashMap不实现。

HashTable已过时,应使用相应的ConcurrentHashMap类。 在此处输入图片说明

哈希图

  • 它具有对值(键,值)
  • 没有重复键值
  • 无序的
  • 它允许一个空键和一个以上的空值

哈希表

  • 与哈希图相同
  • 它不允许空键和空值

LinkedHashMap

  • 它是地图实现的有序版本
  • 基于链表和哈希数据结构

树状图

  • 有序和分类版本
  • 基于哈希数据结构

从我自己使用地图的经验中获得的更多信息,以及何时使用每一个地图的信息:

  • HashMap - 在寻找最佳性能(快速)实现时最有用。
  • TreeMap(SortedMap 接口)- 当我担心能够按我定义的特定顺序对键进行排序或迭代时,此功能最为有用。
  • LinkedHashMap - 结合了从 TreeMap 进行有保证的订购的优点,而不会增加维护 TreeMap 的成本。 (它几乎与 HashMap 一样快)。特别是,LinkedHashMap 还通过重写removeEldestEntry()方法,为创建 Cache 对象提供了一个很好的起点。这使您可以创建一个 Cache 对象,该对象可以使用您定义的某些条件使数据过期。

所有三个类HashMapTreeMapLinkedHashMap实现java.util.Map接口,并表示从唯一键到值的映射。

哈希图

  1. HashMap包含基于键的值。

  2. 它仅包含唯一元素。

  3. 它可能具有一个 null 键和多个 null 值。

  4. 它不保持任何顺序

    public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable

LinkedHashMap

  1. LinkedHashMap包含基于键的值。
  2. 它仅包含唯一元素。
  3. 它可能具有一个 null 键和多个 null 值。
  4. 与 HashMap 相同,只是保持插入顺序// 请参见下面的类减速

    public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>

树状图

  1. TreeMap包含基于键的值。它实现了 NavigableMap 接口并扩展了 AbstractMap 类。
  2. 它仅包含唯一元素。
  3. 它不能有空键,但可以有多个空值。
  4. HashMap相同,只是保持升序 (使用其键的自然顺序排序)。

    public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V>, Cloneable, Serializable

哈希表

  1. 哈希表是列表的数组。每个列表称为存储桶。桶的位置通过调用 hashcode()方法来标识。哈希表包含基于键的值。
  2. 它仅包含唯一元素。
  3. 它可能没有任何空键或值。
  4. 它是同步的
  5. 这是一个遗留类。

    public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, Serializable

参考: http : //javarevisited.blogspot.in/2015/08/difference-between-HashMap-vs-TreeMap-vs-LinkedHashMap-Java.html

HashMap 绝对不保证迭代顺序。添加新元素时,它甚至可以(并将)完全改变。 TreeMap 将根据键的 compareTo()方法(或外部提供的 Comparator)根据键的 “自然顺序” 进行迭代。此外,它实现了 SortedMap 接口,该接口包含依赖于此排序顺序的方法。 LinkedHashMap 将按照将条目放入地图的顺序进行迭代

看一下性能如何变化。 在此处输入图片说明

树图是已排序图的实现。由于自然排序,put,get 和 containsKey 操作的复杂度为 O(log n)

public class TreeMap<K,V>
extends AbstractMap<K,V>
implements SortedMap<K,V>, Cloneable, Serializable

以下是 HashMap 和 TreeMap 之间的主要区别

  1. HashMap 不维护任何顺序。换句话说,HashMap 不能保证首先插入的元素将被首先打印,就像 TreeSet 一样,TreeMap 元素也根据其元素的自然顺序进行排序。

  2. 内部 HashMap 实现使用哈希,而 TreeMap 内部使用 Red-Black 树实现。

  3. HashMap 可以存储一个 null 键和许多 null 值。TreeMap 不能包含 null 键,但可以包含许多 null 值。

  4. HashMap 对诸如 get 和 put 即 O(1)之类的基本操作具有恒定的时间性能。根据 Oracle 文档,TreeMap 为 get 和 put 方法提供了保证的 log(n)时间成本。

  5. HashMap 比 TreeMap 快得多,因为对于大多数操作,HashMap 的性能时间与 TreeMap 的日志时间是恒定的。

  6. HashMap 在比较中使用 equals()方法,而 TreeMap 在使用 compareTo()方法维护排序。

  7. HashMap 实现 Map 接口,而 TreeMap 实现 NavigableMap 接口。