HashMap,LinkedHashMap和TreeMap之间的区别

Java中的HashMapLinkedHashMapTreeMap什么区别? 我没有看到任何输出差异,因为所有三个都有keySetvalues 。 什么是Hashtable

 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()); 

所有三个类都实现了Map接口,并提供了大部分相同的function。 最重要的区别是通过条目迭代的顺序:

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

“散列表”是基于散列的地图的通用名称。 在Java API的上下文中, Hashtable是在集合框架存在之前Java 1.1以前的一个过时的类。 它不应该再被使用了,因为它的API混淆了重复function的过时方法,并且它的方法是同步的(这会降低性能并且通常是无用的)。 使用ConcurrrentHashMap而不是Hashtable。

我更喜欢视觉呈现:

 ╔══════════════╦═════════════════════╦═══════════════════╦═════════════════════╗ ║ Property ║ HashMap ║ TreeMap ║ LinkedHashMap ║ ╠══════════════╬═════════════════════╬═══════════════════╬═════════════════════╣ ║ ║ 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接口。

  1. HashMap是一个基于密钥散列的映射。 它支持O(1)get / put操作。 密钥必须具有hashCode()equals()一致实现才能工作。

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

  3. TreeMap是一个基于树的映射。 它的put / get操作占用O(log n)时间。 它要求项目有一些比较机制,可以用Comparable或Comparator。 迭代次序由这个机制决定。

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

HashTable已经过时,应该使用相应的ConcurrentHashMap类。 在这里输入图像描述

只是从我自己的地图经验的一些input,我什么时候会使用每一个:

  • HashMap – 在寻找最佳性能(快速)实现时最有用。
  • TreeMap(SortedMap接口) – 当我关心能够按照我定义的特定顺序对键进行sorting或遍历时,最有用。
  • LinkedHashMap – 结合TreeMap保证sorting的优点,而不增加维护TreeMap的成本。 (它几乎和HashMap一样快)。 特别的是,LinkedHashMap通过重写removeEldestEntry()方法也为创build一个Cache对象提供了一个很好的起点。 这使您可以使用您定义的某些条件创build可以使数据过期的Cache对象。

HashMap中

  • 它具有配对值(键,值)
  • 没有重复键值
  • 无序未sorting
  • 它允许一个空键和多个空值

哈希表

  • 与散列图相同
  • 它不允许空键和空值

LinkedHashMap的

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

TreeMap的

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

HashMap对迭代次序做了绝对的保证。 当新的元素被添加时,它可以(甚至将会)完全改变。 TreeMap将根据它们的compareTo()方法(或外部提供的比较器)根据键的“自然顺序”进行迭代。 此外,它还实现SortedMap接口,其中包含依赖于此sorting顺序的方法。 LinkedHashMap将按照条目放入地图的顺序迭代

看看性能如何变化.. 在这里输入图像描述

树图是Sorted地图的一个实现。 由于自然sorting,put,get和containsKey操作的复杂度为O(log n)

让我简单说一下:

  • HashMap被实现为一个哈希表,并且没有关键或值的sorting。
  • TreeMap是基于红黑树结构实现的,按键sorting。
  • LinkedHashMap保留了广告订单
  • 与HashMap相比, Hashtable是同步的。 它有一个同步开销。这是如果程序是线程安全的,应该使用HashMap的原因。

@Amit: SortedMap是一个接口,而TreeMap是一个实现SortedMap接口的类。 这意味着如果遵循SortedMap要求其实现者执行的协议。 除非实现为search树,否则树不能为您提供有序的数据,因为树可以是任何种类的树。 因此,为了使TreeMap像sorting顺序一样工作,它实现了SortedMap(例如二进制search树BST,AVL和RB树平衡BST,甚至三元search树 – 主要用于有序迭代search)。

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

在NUT-SHELL HashMap :给出了O(1)中的数据,没有sorting

TreeMap :在O(log N)中给出数据,基数为2

LinkedHashMap :是带有链表的哈希表(想到索引 – SkipList)能够以数据插入树的方式存储数据。 最适合实施LRU(最近最less使用)。

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

HashMap中

  1. HashMap包含基于键的值。

  2. 它只包含独特的元素。

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

  4. 没有维持秩序

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

LinkedHashMap的

  1. LinkedHashMap包含基于密钥的值。
  2. 它只包含独特的元素。
  3. 它可能有一个空键和多个空值。
  4. 和HashMap一样,而不是维护插入顺序//见下面的课程减速

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

TreeMap的

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

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

哈希表

  1. 一个Hashtable是一个列表数组。 每个列表被称为一个桶。 bucket的位置通过调用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

这些是相同接口的不同实现。 每个实现都有一些优点和缺点(快速插入,慢search),反之亦然。

有关详细信息,请查看TreeMap , HashMap , LinkedHashMap的javadoc。

所有提供一个键 – >值映射和一个方法来遍历键。 这些类之间最重要的区别是时间保证和密钥的sorting。

  1. HashMap提供0(1)查找和插入。 但是,如果您遍历键,则键的sorting基本上是任意的。 它由一系列链表实现。
  2. TreeMap提供O(log N)查找和插入。 密钥是有序的,所以如果你需要按照sorting顺序遍历密钥,你可以。 这意味着键必须实现Comparable接口.TreeMap由红黑树实现。
  3. LinkedHashMap提供0(1)查找和插入。 按键按其插入顺序sorting。 它通过双链接桶实施。

假设你将一个空的TreeMap,HashMap和LinkedHashMap传递给下面的函数:

 void insertAndPrint(AbstractMap<Integer, String> map) { int[] array= {1, -1, 0}; for (int x : array) { map.put(x, Integer.toString(x)); } for (int k: map.keySet()) { System.out.print(k + ", "); } } 

每个的输出将如下所示。

对于HashMap,在我自己的testing中,输出是{0,1,-1},但它可以是任何顺序。 订货不保证。
Treemap的输出是{-1,0,1}
LinkedList,输出是{1,-1,0}

HashMap中
可以包含一个空键。

HashMap没有维护顺序。

TreeMap的

TreeMap不能包含任何空键。

TreeMap维护升序。

LinkedHashMap的

LinkedHashMap可用于维护插入顺序,将键插入到Map中,或者也可用于维护访问顺序,在其上访问键。

例子 ::

1)HashMap map = new HashMap();

  map.put(null, "Kamran"); map.put(2, "Ali"); map.put(5, "From"); map.put(4, "Dir");`enter code here` map.put(3, "Lower"); for (Map.Entry m : map.entrySet()) { System.out.println(m.getKey() + " " + m.getValue()); } 

2)TreeMap map = new TreeMap();

  map.put(1, "Kamran"); map.put(2, "Ali"); map.put(5, "From"); map.put(4, "Dir"); map.put(3, "Lower"); for (Map.Entry m : map.entrySet()) { System.out.println(m.getKey() + " " + m.getValue()); } 

3)LinkedHashMap map = new LinkedHashMap();

  map.put(1, "Kamran"); map.put(2, "Ali"); map.put(5, "From"); map.put(4, "Dir"); map.put(3, "Lower"); for (Map.Entry m : map.entrySet()) { System.out.println(m.getKey() + " " + m.getValue()); }