HashMap,LinkedHashMap和TreeMap之间的区别

时间:2010-05-22 21:10:16

标签: java map

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

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

17 个答案:

答案 0 :(得分:1515)

我更喜欢视觉呈现:

╔══════════════╦═════════════════════╦═══════════════════╦═════════════════════╗
║   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               ║
╚══════════════╩═══════════════════════════════════════════════════════════════╝

答案 1 :(得分:1103)

这三个类都实现了Map接口,并提供了大部分相同的功能。最重要的区别在于迭代条目的顺序:

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

"Hashtable"是基于哈希的地图的通用名称。在Java API的上下文中, 在集合框架存在之前,Hashtable是Java 1.1时代的一个过时类。它不应再被使用,因为它的API混杂了复制功能的过时方法,并且它的方法是同步的(这可能会降低性能并且通常是无用的)。使用ConcurrentHashMap代替Hashtable。

答案 2 :(得分:62)

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

  1. HashMap是基于密钥hashing的地图。它支持O(1)get / put操作。密钥必须consistent implementations of hashCode() and equals()才能生效。

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

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

答案 3 :(得分:43)

在下图(bigger one)中查看每个类在类层次结构中的位置。 TreeMap实现了SortedMapNavigableMapHashMap没有。

HashTable已过时,应使用相应的ConcurrentHashMap类。 enter image description here

答案 4 :(得分:37)

HashMap中

  • 它具有配对值(键,值)
  • 没有重复键值
  • unordered unsorted
  • 它允许一个空键和多个空值

哈希表

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

LinkedHashMap的

  • 是地图实施的订购版本
  • 基于链表和散列数据结构

TreeMap的

  • 订购和分拣版
  • 基于散列数据结构

答案 5 :(得分:35)

从我自己的地图经验中获得更多的输入,当我使用每个地图时:

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

答案 6 :(得分:17)

所有三个类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

  5. <强> LinkedHashMap

    1. LinkedHashMap包含基于密钥的值。
    2. 它只包含唯一元素。
    3. 它可能有一个空键和多个空值。
    4. 它与HashMap相同,而是维护 广告订单 //见

      下的课程减速

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

    5. <强> TreeMap

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

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

      5. <强> Hashtable

        1. Hashtable是一个列表数组。每个列表都称为存储桶。通过调用hashcode()方法来识别存储桶的位置。 Hashtable包含基于密钥的值。
        2. 它只包含唯一元素。
        3. 它可能没有任何null键或值。
        4. 已同步
        5. 这是一个遗产类。

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

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

答案 7 :(得分:14)

  

HashMap绝对不能保证迭代顺序。它   当添加新元素时,可以(并且将会)完全改变。   TreeMap将根据&#34;自然排序&#34;迭代。的钥匙   根据他们的compareTo()方法(或外部提供的方法)   比较器)。另外,它实现了SortedMap接口,   其中包含依赖于此排序顺序的方法。 LinkedHashMap的   将按照条目放入地图的顺序进行迭代

看看性能如何变化.. enter image description here

树图,它是Sorted map的一个实现。由于自然排序

,put,get和containsKey操作的复杂性为O(log n)

答案 8 :(得分:9)

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

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

在NUT-SHELL HashMap:在O(1)中提供数据,没有排序

TreeMap:在O(log N)中提供数据,基数为2.使用有序键

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

答案 9 :(得分:6)

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

  1. HashMap不维护任何订单。换句话说,HashMap没有提供任何保证首先插入的元素将首先打印,其中就像TreeSet一样,TreeMap元素也根据其元素的自然顺序排序

  2. 内部HashMap实现使用Hashing和TreeMap在内部使用Red-Black树实现。

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

  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接口。

答案 10 :(得分:5)

这些是同一界面的不同实现。每种实现都有一些优点和一些缺点(快速插入,慢速搜索),反之亦然。

有关详细信息,请查看TreeMapHashMapLinkedHashMap的javadoc。

答案 11 :(得分:4)

  • HashMap中:

    • 订单不维护
    • 比LinkedHashMap更快
    • 用于存储对象堆
  • LinkedHashMap的:

    • 将维护LinkedHashMap广告订单
    • 比HashMap慢,比TreeMap快
    • 如果您想维护广告订单,请使用此广告。
  • TreeMap的:

    • TreeMap是基于树的映射
    • TreeMap将遵循密钥的自然顺序
    • 比HashMap和LinkedHashMap慢
    • 当您需要维护自然(默认)排序时使用TreeMap

答案 12 :(得分:3)

哈希地图不保留插入顺序 例。哈希映射 如果您要插入键

1  3
5  9
4   6
7   15
3   10

它可以将其存储为

4  6
5  9
3  10
1  3
7  15

链接的Hashmap会保留插入顺序。

实施例。
如果要插入密钥

1  3
5  9
4   6
7   15
3   10

它会将其存储为

1  3
5  9
4   6
7   15
3   10

与我们插入相同。

树形图将值存储在“增加键的顺序”中。 例子。
如果要插入密钥

1  3
5  9
4   6
7   15
3   10

它会将其存储为

1  3
3  10
4   6
5   9
7   15

答案 13 :(得分:1)

所有提供了key-&gt;值映射以及迭代键的方法。最重要的区别 这些类是时间保证和密钥的排序。

  1. HashMap提供0(1)查找和插入。但是,如果你遍历键,那么顺序就是 键本质上是任意的。它由一系列链表实现。
  2. TreeMap提供O(log N)查找和插入。键是有序的,所以如果你需要迭代 按顺序排列的键,你可以。这意味着键必须实现Comparable接口.TreeMap由红黑树实现。
  3. LinkedHashMap提供0(1)查找和插入。密钥按其插入顺序排序。它是 由双重链接的桶实现。
  4. 想象一下,您将空的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,输出在我自己的测试中是{0,1,-1},但它可以是任何排序。没有保证 排序。
    树形图,输出为,{-1,0,1}
    LinkedList,输出为{1,-1,0}

答案 14 :(得分:0)

<强> HashMap中
可以包含一个空键。

HashMap不维序。

<强> TreeMap的

TreeMap不能包含任何null键。

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

答案 15 :(得分:0)

这三者中最重要的是它们如何保存条目的顺序。

HashMap-不保存条目的顺序。 例如。

public static void main(String[] args){
        HashMap<String,Integer> hashMap = new HashMap<>();
        hashMap.put("First",1);// First ---> 1 is put first in the map
        hashMap.put("Second",2);//Second ---> 2 is put second in the map
        hashMap.put("Third",3); // Third--->3 is put third in the map
        for(Map.Entry<String,Integer> entry : hashMap.entrySet())
        {
            System.out.println(entry.getKey()+"--->"+entry.getValue());
        }
    }

Output for HashMap

LinkedHashMap:保存输入条目的顺序。例如:

public static void main(String[] args){
        LinkedHashMap<String,Integer> linkedHashMap = new LinkedHashMap<>();
        linkedHashMap.put("First",1);// First ---> 1 is put first in the map
        linkedHashMap.put("Second",2);//Second ---> 2 is put second in the map
        linkedHashMap.put("Third",3); // Third--->3 is put third in the map
        for(Map.Entry<String,Integer> entry : linkedHashMap.entrySet())
        {
            System.out.println(entry.getKey()+"--->"+entry.getValue());
        }
    }

Output of LinkedHashMap

TreeMap:按键的升序保存条目。例如:

public static void main(String[] args) throws IOException {
        TreeMap<String,Integer> treeMap = new TreeMap<>();
        treeMap.put("A",1);// A---> 1 is put first in the map
        treeMap.put("C",2);//C---> 2 is put second in the map
        treeMap.put("B",3); //B--->3 is put third in the map
        for(Map.Entry<String,Integer> entry : treeMap.entrySet())
        {
            System.out.println(entry.getKey()+"--->"+entry.getValue());
        }
    }

Output of TreeMap

答案 16 :(得分:0)

尽管这里有很多出色的答案,但我想展示自己的表格,描述与Java 11捆绑在一起的各种Map实现。

我们可以在表格图形中看到这些差异:

  • HashMap通用 Map,在您没有特殊需要时通常使用。
  • LinkedHashMap扩展了HashMap,添加了以下行为:维持顺序,即最初添加条目的顺序。更改键值输入的值不会更改其在顺序中的位置。
  • TreeMap也维持顺序,但使用(a)“自然”顺序中的任何一个,这意味着compareTo方法的值在Comparable界面,或(b)调用您提供的 Comparator实现
  • NULLTreeMap确实 不允许不允许将NULL作为键,而HashMapLinkedHashMap做。
    • 三个都允许NULL作为值。
  • HashTable legacy,来自Java 1 。由ConcurrentHashMap类取代。引用Javadoc:ConcurrentHashMap遵循与Hashtable相同的功能规范,并包括与Hashtable的每个方法相对应的方法版本。

Table listing attributes of the various implementations of <code>Map</code> bundled with Java 11.