枚舉詳解之EnumSet、EnumMap用法


枚舉簡單例子
/** * @author shuliangzhao * @Title: Color * @ProjectName design-parent * @Description: TODO * @date 2019/6/12 22:35 */ public enum Color { YELLOW, RED, BLUE, PURPLE, BLACK; } 
/** * @author shuliangzhao * @Title: ColorEnumTest * @ProjectName design-parent * @Description: TODO * @date 2019/6/12 22:37 */ public class ColorEnumTest { public static void main(String[] args) { Color color = Color.BLUE; switch (color) { case RED: System.out.println("紅色"); break; case BLUE: System.out.println("藍色"); break; case PURPLE: System.out.println("紫色"); break; case BLACK: System.out.println("黑色"); break; case YELLOW: System.out.println("黃色"); break; default: System.out.println("藍色"); break; } } } 

測試結果

 

 
image.png

Color枚舉的本質就是一個類,編譯器會自動為我們生成Color類,通過反編譯得到該類如下:

final class Color extends Enum { //編譯器為我們添加的靜態的values()方法 public static Color[] values() { return (Color[])$VALUES.clone(); } //編譯器為我們添加的靜態的valueOf()方法,注意間接調用了Enum也類的valueOf方法 public static Color valueOf(String s) { return (Color)Enum.valueOf(com/sl/emun/Color, s); } //私有構造函數 private Color(String s, int i) { super(s, i); } //前面定義的7種枚舉實例 public static final Color YELLOW; public static final Color RED; public static final Color BLUE; public static final Color PURPLE; public static final Color BLACK; private static final Color $VALUES[]; static { //實例化枚舉實例 YELLOW = new Color("YELLOW", 0); RED = new Color("RED", 1); BLUE = new Color("BLUE", 2); PURPLE = new Color("PURPLE", 3); BLACK = new Color("BLACK", 4); $VALUES = (new Color[] { YELLOW, RED, BLUE, PURPLE, BLACK }); } } 

可以看出每個枚舉類型顏色是該Color類的一個實例對象,該構成方式和單例模式有些類似,故可以用只有一個枚舉類型的枚舉作為單例模式,而且枚舉的構造器由編譯器管理安全性十分高,既可以防止反射破解也可以防止反序列破解。

EnumMap用法
/** * @author shuliangzhao * @Title: EnumMapTest * @ProjectName design-parent * @Description: TODO * @date 2019/6/12 22:49 */ public class EnumMapTest { public static void main(String[] args) { EnumMap<Color,String> enumMap = new EnumMap(Color.class); enumMap.put(Color.BLACK,"黑色"); enumMap.put(Color.BLUE,"藍色"); System.out.println(enumMap); System.out.println(enumMap.get(Color.BLUE)); } } 

運行結果

 

 
image.png

EnumMap put方法

public V put(K key, V value) { typeCheck(key); int index = key.ordinal(); Object oldValue = vals[index]; vals[index] = maskNull(value); if (oldValue == null) size++; return unmaskNull(oldValue); } 

首先調用typeCheck檢查鍵的類型,如果類型不對,會拋出異常。類型正確的話,調用ordinal獲取索引index,並將值value放入值數組vals[index]中。EnumMap允許值為null,為了區別null值與沒有值,EnumMap將null值包裝成了一個特殊的對象,有兩個輔助方法用於null的打包和解包,打包方法為maskNull,解包方法為unmaskNull。

get方法

public V get(Object key) { return (isValidKey(key) ? unmaskNull(vals[((Enum<?>)key).ordinal()]) : null); } 

鍵有效的話,通過ordinal方法取索引,然后直接在值數組vals里找。isValidKey的代碼與typeCheck類似,但是返回boolean值而不是拋出異常。

以上就是EnumMap的基本實現原理,內部有兩個數組,長度相同,一個表示所有的鍵,一個表示對應的值,值為null表示沒有該鍵值對,鍵都有一個對應的索引,根據索引可直接訪問和操作其鍵和值,效率很高。

EnumSet

EnumSet這是一個用來操作Enum的集合,是一個抽象類,它有兩個繼承類:JumboEnumSet和RegularEnumSet。在使用的時候,需要確定枚舉類型。它的特點也是速度非常快,為什么速度很快呢?因為每次add的時候,每個枚舉值只占一個長整型的一位。
EnumSet.noneOf()方法創建一個空的set

public class EnumSetTest { public static void main(String[] args) { EnumSet<Color> enumSet = EnumSet.noneOf(Color.class); System.out.println(enumSet); enumSet.add(Color.BLUE); enumSet.add(Color.PURPLE); System.out.println(enumSet); } } 

運行結果

 

 
image.png

EnumSet.allOf()方法創建一個滿的set

/** * @author shuliangzhao * @Title: EnumSetTest * @ProjectName design-parent * @Description: TODO * @date 2019/6/12 23:24 */ public class EnumSetTest { public static void main(String[] args) { /*EnumSet<Color> enumSet = EnumSet.noneOf(Color.class); System.out.println(enumSet); enumSet.add(Color.BLUE); enumSet.add(Color.PURPLE); System.out.println(enumSet);*/ EnumSet<Color> enumSet = EnumSet.allOf(Color.class); System.out.println(enumSet); } } 

運行結果

 

 
image.png

EnumSet.range創建指定范圍set

public class EnumSetTest { public static void main(String[] args) { /*EnumSet<Color> enumSet = EnumSet.noneOf(Color.class); System.out.println(enumSet); enumSet.add(Color.BLUE); enumSet.add(Color.PURPLE); System.out.println(enumSet); EnumSet<Color> enumSet = EnumSet.allOf(Color.class); System.out.println(enumSet);*/ EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE); System.out.println(enumSet); } } 
 
image.png

EnumSet.complementOf補集創建set

public class EnumSetTest { public static void main(String[] args) { /*EnumSet<Color> enumSet = EnumSet.noneOf(Color.class); System.out.println(enumSet); enumSet.add(Color.BLUE); enumSet.add(Color.PURPLE); System.out.println(enumSet); EnumSet<Color> enumSet = EnumSet.allOf(Color.class); System.out.println(enumSet);*/ EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE); System.out.println(enumSet); EnumSet<Color> enumSet1 = EnumSet.complementOf(enumSet); System.out.println(enumSet1); } } 

運行結果

 

 
image.png

EnumSet.copyOf復制創建set

public class EnumSetTest { public static void main(String[] args) { /*EnumSet<Color> enumSet = EnumSet.noneOf(Color.class); System.out.println(enumSet); enumSet.add(Color.BLUE); enumSet.add(Color.PURPLE); System.out.println(enumSet); EnumSet<Color> enumSet = EnumSet.allOf(Color.class); System.out.println(enumSet); EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE); System.out.println(enumSet); EnumSet<Color> enumSet1 = EnumSet.complementOf(enumSet); System.out.println(enumSet1);*/ EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE); System.out.println(enumSet); EnumSet<Color> enumSet1 = EnumSet.copyOf(enumSet); System.out.println(enumSet1); } } 

運行結果

 

 
image.png

EnumSet.copyOf復制創建集合

public class EnumSetTest { public static void main(String[] args) { /*EnumSet<Color> enumSet = EnumSet.noneOf(Color.class); System.out.println(enumSet); enumSet.add(Color.BLUE); enumSet.add(Color.PURPLE); System.out.println(enumSet); EnumSet<Color> enumSet = EnumSet.allOf(Color.class); System.out.println(enumSet); EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE); System.out.println(enumSet); EnumSet<Color> enumSet1 = EnumSet.complementOf(enumSet); System.out.println(enumSet1); EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE); System.out.println(enumSet); EnumSet<Color> enumSet1 = EnumSet.copyOf(enumSet); System.out.println(enumSet1);*/ List<Color> colors = new ArrayList<>(); colors.add(Color.PURPLE); colors.add(Color.BLUE); colors.add(Color.BLUE); System.out.println(colors); EnumSet<Color> enumSet = EnumSet.copyOf(colors); System.out.println(enumSet); } } 

運行結果

 

 
image.png

注意:通過結果可以看出ArrayList內放置的元素可以重復,而EnumSet內放置的元素不重復。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM