Java 8 HashMap Reading memo
3 min readAug 21, 2020
1. 大致上的特性跟 HashTable 差不多, 但沒有 synchronized 保證, 也允許 null key 與 value.
2. 在操作 get, put 時, 操作的時間是一個 constant-time performance 操作, 這邊牽涉到一個 factor 0.75 的設計, 非常深… Orz
3. 官方文件解釋說 .75 是一個交換時間與記憶體空間的消耗比, 若 factor 高於 .75 會減少空間開銷, 但會提高搜尋 Hash 的成本, 反之則相對.
4. 如果 capacity > entries 數量 / 0.75, 就不會做 ReHash 計算, 簡單翻譯為
int cap = 16; // 預設 16 個 entries 的容量float fact = 0.75;HashMap _map = new HashMap(cap);// 如果 capacity 已經達到 3/4, 除了擴充 capacity, 還做 reHash, 細節可能要翻一下 API Source code.if (cap * 0.75 < _map.size()) { reHash();}
5. 詳細公式大概可以看這篇吧 https://www.jianshu.com/p/64f6de3ffcc1
6. Important! 如果在 multi-thread 下操作 HashMap 應該要採用 synchronized, 在 JAVA 8 可以用這個寫法
Map m = Collections.synchronizedMap(new HashMap(…));
7. 而最後要小心的是 HashMap 在轉為 Iterator 操作的時候, 要特別注意 Map 結構的操作, 這會造成 ConcurrentModificationException
@Testvoid testing() { int cap = 16; // 要 entries 數量大於 2 才會拋出 ConcurrentModificationException Map<String, String> m = new HashMap<>(cap); m.put(“key1”, “value1”); m.put(“key2”, “value2”);
Iterator<Entry<String, String>> it = m.entrySet().iterator(); while (it.hasNext()) { Entry<String, String> entry = it.next(); // 這個 remove 就會破壞 Map 的結構導致 Exception m.remove(entry.getKey()); }}