原文: https://javatutorial.net/difference-between-hashmap-and-treemap-in-java

在本文中,我将解释 java HashMap和 java TreeMap之间的区别

尽管两者都实现了Map接口并提供了大多数相同的功能,但是HashMapTreeMap具有不同的实现。 最重要的区别是通过条目进行迭代的顺序

查看下表,直观了解HashMapTreeMap之间的区别

Java 中`HashMap`和`TreeMap`之间的区别 - 图1

Java 中HashMapTreeMap之间的区别

HashMapTreeMap之间的主要区别

TreeMapSortedMap的示例,由红黑树实现,这意味着对键的顺序进行了排序。 遍历键时,您可以依靠它们会井然有序的事实。 键的顺序由元素的compareTo()方法或外部提供的比较器确定。

HashMap则不做任何保证。 它由哈希表实现。 因此,当迭代HashMap的键时,您不能确定它们将以什么顺序排列。

看下面的例子:

  1. package javatutorial.net;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import java.util.TreeMap;
  5. public class HashMapVsTreeMapExample {
  6. public static void main(String[] args) {
  7. Map<Integer, String> hMap = new HashMap<Integer, String>();
  8. hMap.put(5, "A");
  9. hMap.put(11, "C");
  10. hMap.put(4, "Z");
  11. hMap.put(77, "Y");
  12. hMap.put(9, "P");
  13. hMap.put(66, "Q");
  14. hMap.put(0, "R");
  15. Map<Integer, String> tMap = new TreeMap<Integer, String>();
  16. tMap.put(5, "A");
  17. tMap.put(11, "C");
  18. tMap.put(4, "Z");
  19. tMap.put(77, "Y");
  20. tMap.put(9, "P");
  21. tMap.put(66, "Q");
  22. tMap.put(0, "R");
  23. System.out.println("HashMap iteration order =======");
  24. for (Map.Entry<Integer, String> entry : hMap.entrySet()) {
  25. System.out.println(entry.getKey() + " = " + entry.getValue());
  26. }
  27. System.out.println("\nTreeMap iteration order =======");
  28. for (Map.Entry<Integer, String> entry : tMap.entrySet()) {
  29. System.out.println(entry.getKey() + " = " + entry.getValue());
  30. }
  31. }
  32. }

现在看一下该程序的输出:

  1. HashMap iteration order =======
  2. 0 = R
  3. 66 = Q
  4. 4 = Z
  5. 5 = A
  6. 9 = P
  7. 11 = C
  8. 77 = Y
  9. TreeMap iteration order =======
  10. 0 = R
  11. 4 = Z
  12. 5 = A
  13. 9 = P
  14. 11 = C
  15. 66 = Q
  16. 77 = Y

如您所见,在HashMap上进行迭代时,我们以“随机”顺序获得条目。 另一方面,TreeMap迭代以其自然顺序返回条目。

实现复杂度差异

由于HashMap实现的复杂度为O(1),因此通常可以认为HashMap效率更高,因此无论您何时在乎键的顺序,都可以使用它。 另一方面,TreeMap中获取,放置和删除操作的复杂度为 O(log n)

允许的键和值的差异

另一个重要的区别是,HashMap允许使用null键和值,而TreeMap仅允许将null用作其值。

同步(无差异)

请注意,两个实现都不同步,这意味着在这些映射上进行操作不是线程安全的。 如果需要线程安全的Map,则可能要从java.util.concurrent包中选择ConcurrentHashMap类。 这是Map的线程安全实现,比Collections.synchronizedMap(Map<K,V> m)提供更好的并发性