典型的回答
Hashtable、HashMap、TreeMap都是最常見的Map接口的實現,是以鍵值對的形式存儲和操作數據的容器類型。
Hashtable是早期Java類庫提供的一個哈希表實現,本身是線程安全的,不支持null鍵和值。由於線程安全導致的性能開銷,所以已經很少被推薦使用。
HashMap是應用更加廣泛的哈希表實現,行為上大致與Hashtable一致,主要區別在於HashMap不是線程安全的,且支持null鍵和值等。通常情況下,HashMap進行put或者get操作,可以達到常數時間的性能,所以它是絕大部分利用鍵值對存取場景的首選。
TreeMap則是基於紅黑樹的一種提供順序訪問的Map,和HashMap不同,它的get、put、remove之類操作都是O(log(n))的時間複雜度,具體順序可以由指定的Comparator來決定,或者根據鍵的自然順序來判斷。
知識擴展
1、Map整體結構
Map被包括在Java集合框架裡,但其本身並不是狹義上的集合類型(Collection)。
Hashtable比較特別,作為類似Vector、Stack的早期集合相關類型,它是擴展了Dictionary類,結構上與HashMap之類明顯不同。
大部分使用Map的場景,通常就是放入、訪問或者刪除,而對順序沒有特別要求。
HashMap在這種情況下基本上是最好的選擇。HashMap的性能表現非常依賴於哈希碼的有效性,請務必掌握hashCode和equals的一些基本約定:
01
equals相等,hashCode一定要相等。
02
重寫了hashCode也要重寫equals。
03
hashCode需要保持一致性,狀態改變返回的哈希值仍然要一致。
04
equals要滿足對稱、反射與傳遞性。
還有部分使用Map的場景中,對於鍵值對的順序是有要求的。這時就應該考慮使用LinkedHashMap和TreeMap。
2、LinkedHashMap vs. TreeMap
雖然LinkedHashMap和TreeMap都可以保證某種順序,但二者還是非常不同的。
TreeMap是利用紅黑樹來實現的。樹中的每個節點的值,都會大於或等於它的左子樹中的所有節點的值,並且小於或等於它的右子樹中的所有節點的值。它實現了SortedMap接口,能夠對保存的記錄根據鍵進行排序。也就是說TreeMap的整體順序是由鍵的順序關係決定的,通過Comparator或Comparable(自然順序)來決定。類似於hashCode和equals的約定,為了避免模稜兩可的情況,自然順序同樣需要符合一個約定:compareTo的返回值需要和equals一致。
LinkedHashMap通常提供的是遍歷順序符合插入順序。它的實現是通過為條目(鍵值對)維護一個雙向鏈表。注意,通過特定的構造函數,我們可以創建反映訪問順序的實例,所謂的put、get、compute等,都算作“訪問”。
這種行為適用於一些特定應用場景,例如,我們構建一個空間佔用敏感的資源池,希望可以自動將最不常被訪問的對象釋放掉,這就可以利用LinkedHashMap提供的機制來實現。參考以下示例:
public class LinkedHashMapSample {
public static void main(String[] args) {
LinkedHashMap
@Override
protected boolean removeEldestEntry(Map.Entry eldest) {
// 實現自定義的刪除策略,否則行為就和普通Map沒有區別。
return size() > 3;
}
};
map.put("Project1", "Apple");
map.put("Project2", "Banana");
map.put("Project3", "Cherry");
map.forEach((k, v) -> {
System.out.println(k + ":" + v);
});
// 模擬訪問
map.get("Project2");
map.get("Project2");
map.get("Project3");
System.out.println();
map.forEach((k, v) -> {
System.out.println(k + ":" + v);
});
// 觸發刪除
map.put("Project4", "Mango");
System.out.println();
map.forEach((k, v) -> {
System.out.println(k + ":" + v);
});
}
}
輸出如下:
Project1:Apple
Project2:Banana
Project3:Cherry
Project1:Apple
Project2:Banana
Project3:Cherry
Project2:Banana
Project3:Cherry
Project4:Mango
閱讀更多 java面試筆試 的文章