EnumMap指南
1.概述
EnumMap是一個*Map實現,專門將Enum*作為其鍵。
在本教程中,我們將討論其屬性,常見用例以及何時使用它。
2.搭建項目
想像一下一個簡單的要求,我們需要根據當天的運動情況來繪製一周中的幾天:
Monday Soccer
Tuesday Basketball
Wednesday Hiking
Thursday Karate
為此,我們可以使用一個枚舉:
public enum DayOfWeek {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
我們很快會看到的將是地圖的關鍵。
3.實例化
要開始探索EnumMap ,首先我們需要實例化一個:
EnumMap<DayOfWeek, String> activityMap = new EnumMap<>(DayOfWeek.class);
activityMap.put(DayOfWeek.MONDAY, "Soccer");
這是我們與更常見的東西(例如HashMap )的第一個區別。注意,使用HashMap ,類型參數化就足夠了,這意味著我們可以使用新的HashMap <>()。**但是, EnumMap需要構造函數中的鍵類型**。
3.1。 EnumMap複製構造函數
EnumMap還附帶了兩個副本構造函數。第一個使用另一個EnumMap :
EnumMap<DayOfWeek, String> activityMap = new EnumMap<>(DayOfWeek.class);
activityMap.put(DayOfWeek.MONDAY, "Soccer");
activityMap.put(DayOfWeek.TUESDAY, "Basketball");
EnumMap<DayOfWeek, String> activityMapCopy = new EnumMap<>(dayMap);
assertThat(activityMapCopy.size()).isEqualTo(2);
assertThat(activityMapCopy.get(DayOfWeek.MONDAY)).isEqualTo("Soccer");
assertThat(activityMapCopy.get(DayOfWeek.TUESDAY)).isEqualTo("Basketball");
3.2。Map複製構造函數
或者,如果我們有一個鍵為枚舉的非空Map ,那麼我們也可以這樣做:
Map<DayOfWeek, String> ordinaryMap = new HashMap();
ordinaryMap.put(DayOfWeek.MONDAY, "Soccer");
EnumMap enumMap = new EnumMap(ordinaryMap);
assertThat(enumMap.size()).isEqualTo(1);
assertThat(enumMap.get(DayOfWeek.MONDAY)).isEqualTo("Soccer");
請注意,映射必須為非空,以便EnumMap可以從現有條目中確定鍵類型。
如果指定的映射包含多個枚舉類型,則構造方法將拋出ClassCastException 。
4.添加和檢索元素
實例化一個EnumMap之後,我們可以使用put()方法添加運動:
activityMap.put(DayOfWeek.MONDAY, "Soccer");
為了獲取它,我們可以使用get() :
assertThat(clubMap.get(DayOfWeek.MONDAY)).isEqualTo("Soccer");
5.檢查元素
要檢查是否有針對特定日期定義的映射,我們使用containsKey() :
activityMap.put(DayOfWeek.WEDNESDAY, "Hiking");
assertThat(activityMap.containsKey(DayOfWeek.WEDNESDAY)).isTrue();
並且,要檢查特定運動是否映射到任何鍵,我們使用containsValue() :
assertThat(activityMap.containsValue("Hiking")).isTrue();
5.1。null空值
現在, null是EnumMap的語義有效值。
讓我們將null與“無所事事”相關聯,然後將其映射到Saturday:
assertThat(activityMap.containsKey(DayOfWeek.SATURDAY)).isFalse();
assertThat(activityMap.containsValue(null)).isFalse();
activityMap.put(DayOfWeek.SATURDAY, null);
assertThat(activityMap.containsKey(DayOfWeek.SATURDAY)).isTrue();
assertThat(activityMap.containsValue(null)).isTrue();
6.移除元素
為了取消特定日期的映射,我們只需將其remove() :
activityMap.put(DayOfWeek.MONDAY, "Soccer");
assertThat(activityMap.remove(DayOfWeek.MONDAY)).isEqualTo("Soccer");
assertThat(activityMap.containsKey(DayOfWeek.MONDAY)).isFalse();
如我們所見,remove(key)返回與該鍵關聯的先前值;如果沒有該鍵的映射,則返回null 。
我們還可以選擇**僅取消映射特定日期的特定日期:**
activityMap.put(DayOfWeek.Monday, "Soccer");
assertThat(activityMap.remove(DayOfWeek.Monday, "Hiking")).isEqualTo(false);
assertThat(activityMap.remove(DayOfWeek.Monday, "Soccer")).isEqualTo(true);
僅當鍵當前映射到指定值時,remove(key,value)才刪除指定鍵的條目。
7.集合視圖
就像普通地圖一樣,使用任何EnumMap ,我們可以擁有3個不同的視圖或子集合。
首先,讓我們為我們的活動創建一個新的地圖:
EnumMap<DayOfWeek, String> activityMap = new EnumMap(DayOfWeek.class);
activityMap.put(DayOfWeek.THURSDAY, "Karate");
activityMap.put(DayOfWeek.WEDNESDAY, "Hiking");
activityMap.put(DayOfWeek.MONDAY, "Soccer");
7.1。values
我們的活動地圖的第一個視圖是*values()* ,顧名思義,它返回地圖中的所有值:
Collection values = dayMap.values();
assertThat(values)
.containsExactly("Soccer", "Hiking", "Karate");
請注意,此處的EnumMap是有序地圖。它使用DayOfWeek枚舉的順序來確定條目的順序。
7.2。keySet
類似地, *keySet()*再次以枚舉順序返回鍵的集合:
Set keys = dayMap.keySet();
assertThat(keys)
.containsExactly(DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY, DayOfWeek.SATURDAY);
7.3。 entrySet
最後, *entrySet()*以鍵和值對的形式返回映射:
assertThat(dayMap.entrySet())
.containsExactly(
new SimpleEntry(DayOfWeek.MONDAY, "Soccer"),
new SimpleEntry(DayOfWeek.WEDNESDAY, "Hiking"),
new SimpleEntry(DayOfWeek.THURSDAY, "Karate")
);
地圖中的排序當然可以派上用場,並且我們在將TreeMap與HashMap進行比較的教程中進行了更深入的介紹。
7.4。可變性
現在,請記住,我們對原始活動map所做的任何更改都將反映在其任何視圖中:
activityMap.put(DayOfWeek.TUESDAY, "Basketball");
assertThat(values)
.containsExactly("Soccer", "Basketball", "Hiking", "Karate");
反之亦然;我們對子視圖所做的任何更改都將反映在原始活動map中:
values.remove("Hiking");
assertThat(activityMap.containsKey(DayOfWeek.WEDNESDAY)).isFalse();
assertThat(activityMap.size()).isEqualTo(3);
根據EnumMap與Map接口的合同,子視圖由原始地圖支持。
8.何時使用EnumMap
8.1。性能
使用Enum作為鍵可以進行一些額外的性能優化,例如更快的哈希計算,因為所有可能的鍵都是預先知道的。
以枚舉作為鍵的簡單性意味著EnumMap只需要由一個普通的Java Array進行備份,該Java Array具有非常簡單的存儲和檢索邏輯。另一方面,通用Map實現需要解決與將通用對像作為其鍵有關的問題。例如, HashMap需要復雜的數據結構以及相當複雜的存儲和檢索邏輯,以解決哈希衝突的可能性。
8.2。功能性
同樣,如我們所見, EnumMap是一個有序映射,因為它的視圖將以枚舉順序進行迭代。為了在更複雜的場景中獲得類似的行為,我們可以查看TreeMap或LinkedHashMap 。
9.結論
在本文中,我們探討了Map接口的EnumMap實現。當使用Enum作為鍵時, EnumMap會派上用場。
本教程中使用的所有示例的完整源代碼都可以在GitHub項目中找到。