枚举详解之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 {//編譯器為我們添加的靜態(tài)的values()方法public static Color[] values(){return (Color[])$VALUES.clone();}//編譯器為我們添加的靜態(tài)的valueOf()方法,注意間接調用了Enum也類的valueOf方法public static Color valueOf(String s){return (Color)Enum.valueOf(com/sl/emun/Color, s);}//私有構造函數(shù)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放入值數(shù)組vals[index]中。EnumMap允許值為null,為了區(qū)別null值與沒有值,EnumMap將null值包裝成了一個特殊的對象,有兩個輔助方法用于null的打包和解包,打包方法為maskNull,解包方法為unmaskNull。
get方法
public V get(Object key) {return (isValidKey(key) ?unmaskNull(vals[((Enum<?>)key).ordinal()]) : null);}鍵有效的話,通過ordinal方法取索引,然后直接在值數(shù)組vals里找。isValidKey的代碼與typeCheck類似,但是返回boolean值而不是拋出異常。
以上就是EnumMap的基本實現(xiàn)原理,內部有兩個數(shù)組,長度相同,一個表示所有的鍵,一個表示對應的值,值為null表示沒有該鍵值對,鍵都有一個對應的索引,根據(jù)索引可直接訪問和操作其鍵和值,效率很高。
EnumSet
EnumSet這是一個用來操作Enum的集合,是一個抽象類,它有兩個繼承類:JumboEnumSet和RegularEnumSet。在使用的時候,需要確定枚舉類型。它的特點也是速度非常快,為什么速度很快呢?因為每次add的時候,每個枚舉值只占一個長整型的一位。
EnumSet.noneOf()方法創(chuàng)建一個空的set
運行結果
?
image.png
EnumSet.allOf()方法創(chuàng)建一個滿的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創(chuàng)建指定范圍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補集創(chuàng)建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復制創(chuàng)建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復制創(chuàng)建集合
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內放置的元素不重復。
總結
以上是生活随笔為你收集整理的枚举详解之EnumSet、EnumMap用法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java并发编程系列之Semaphore
- 下一篇: 设计模式-装饰模式(Decorator