一文弄懂EnumMap和EnumSet
簡介
一般來說我們會選擇使用HashMap來存儲key-value格式的數據,考慮這樣的特殊情況,一個HashMap的key都來自於一個Enum類,這樣的情況則可以考慮使用本文要講的EnumMap。
EnumMap
先看一下EnumMap的定義和HashMap定義的比較:
public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>
implements java.io.Serializable, Cloneable
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
我們可以看到EnumMap幾乎和HashMap是一樣的,區別在於EnumMap的key是一個Enum。
下面看一個簡單的使用的例子:
先定義一個Enum:
public enum Types {
RED, GREEN, BLACK, YELLO
}
再看下怎麼使用EnumMap:
@Test
public void useEnumMap(){
EnumMap<Types, String> activityMap = new EnumMap<>(Types.class);
activityMap.put(Types.BLACK,"black");
activityMap.put(Types.GREEN,"green");
activityMap.put(Types.RED,"red");
}
其他的操作其實和hashMap是類似的,我們這裏就不多講了。
什麼時候使用EnumMap
因爲在EnumMap中,所有的key的可能值在創建的時候已經知道了,所以使用EnumMap和hashMap相比,可以提升效率。
同時,因爲key比較簡單,所以EnumMap在實現中,也不需要像HashMap那樣考慮一些複雜的情況。
EnumSet
跟EnumMap很類似,EnumSet是一個set,然後set中的元素都是某個Enum類型。
EnumSet是一個interface而不是一個類,要創建EnumSet類可以使用EnumSet提供的兩個靜態方法,noneOf和allOf。
先看一個noneOf:
public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
Enum<?>[] universe = getUniverse(elementType);
if (universe == null)
throw new ClassCastException(elementType + " not an enum");
if (universe.length <= 64)
return new RegularEnumSet<>(elementType, universe);
else
return new JumboEnumSet<>(elementType, universe);
}
noneOf傳入一個Enum類,返回一個空的Enum類型的EnumSet。
從上面的代碼我們可以看到EnumSet有兩個實現,長度大於64的時候使用JumboEnumSet,小有64的時候使用RegularEnumSet。
注意,JumboEnumSet和RegularEnumSet不建議直接使用,他是內部使用的類。
再看一下allOf:
public static <E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType) {
EnumSet<E> result = noneOf(elementType);
result.addAll();
return result;
}
allOf很簡單,先調用noneOf創建空的set,然後調用addAll方法將所有的元素添加進去。
總結
EnumMap和EnumSet對特定的Enum對象做了優化,可以在合適的情況下使用。
本文的例子https://github.com/ddean2009/learn-java-collections
歡迎關注我的公衆號:程序那些事,更多精彩等着您!
更多內容請訪問 www.flydean.com