一句话说透Java里面的HashMap与TreeMap、HashTable的区别

181 阅读2分钟

一、核心区别对比

对比项HashMapTreeMapHashTable
底层实现哈希表(数组+链表/红黑树)红黑树(平衡二叉搜索树)哈希表(类似HashMap)
线程安全非线程安全非线程安全线程安全(全表锁)
键值顺序无序按键自然顺序或自定义排序无序
Null键值✅ 允许null键和null值❌ 键不能为null(值可null)❌ 键值均不能为null
性能特点查询极快(O(1))查询较慢(O(log n))性能差(锁开销)
扩容机制动态扩容(默认2倍)无需扩容(树自动平衡)动态扩容
推荐场景高频查询、无需排序需要排序或范围查询遗留代码或特定兼容场景

二、适用场景

1. 用 HashMap
  • 场景

    • 需要快速存取键值对,不关心顺序。
    • 单线程环境或已自行处理线程安全。
    • 允许键或值为 null
  • 示例

    Map<String, Integer> scores = new HashMap<>();  
    scores.put("Alice", 90);  
    scores.put(null, 0); // 允许null键  
    int score = scores.get("Alice"); // 快速查询  
    
2. 用 TreeMap
  • 场景

    • 需要按键排序(如字典序、数值大小)。
    • 需要范围查询(如找大于某值的键)。
    • 键需自定义排序规则(传入 Comparator)。
  • 示例

    // 按年龄降序排序  
    Map<String, Integer> ageMap = new TreeMap<>((a, b) -> b.compareTo(a));  
    ageMap.put("Bob", 25);  
    ageMap.put("Alice", 30);  
    // 输出顺序:Bob=25 → Alice=30(按键降序)  
    
    // 范围查询:获取键在 "A""C" 之间的条目  
    SortedMap<String, Integer> subMap = ((TreeMap<String, Integer>)ageMap).subMap("A", "C");  
    
3. 用 HashTable(已过时)
  • 场景

    • 遗留系统或需要兼容老代码。
    • 需要线程安全且无法升级到 ConcurrentHashMap
  • 注意:现代Java开发中,优先用 ConcurrentHashMap(分段锁,性能更好)。


三、性能取舍

  • HashMap vs TreeMap

    • HashMap:牺牲顺序换速度。
    • TreeMap:牺牲速度换顺序。
  • HashTable vs ConcurrentHashMap

    • HashTable:全表锁,并发性能差。
    • ConcurrentHashMap:分段锁,高并发下更优。

四、经典对比示例

1. 统计单词频率(无需排序)→ HashMap
Map<String, Integer> wordCount = new HashMap<>();  
String text = "apple banana apple orange";  
for (String word : text.split(" ")) {  
    wordCount.put(word, wordCount.getOrDefault(word, 0) + 1);  
}  
// 结果:{banana=1, orange=1, apple=2}(顺序随机)  
2. 按学生ID排序显示 → TreeMap
Map<String, Integer> students = new TreeMap<>();  
students.put("S002", 85);  
students.put("S001", 90);  
// 结果:{S001=90, S002=85}(按键升序)  
3. 多线程环境 → ConcurrentHashMap(替代HashTable)
Map<String, String> safeMap = new ConcurrentHashMap<>();  
safeMap.put("key", "value"); // 线程安全,分段锁  

五、总结口诀

「HashMap 快如闪电,无序存取是首选
TreeMap 自动排,范围查询更方便
HashTable 已过时,并发推荐 Concurrent
按需选择三兄弟,场景匹配最关键!」