java列舉初學習
歷史
列舉是JDK1.5版本新增的特性(泛型、For-each等如今被廣泛應用的特性也是由JDK1.5時所新增的),另外到了JDK1.6後switch語句支援列舉型別。
列舉概念
它是一種新的型別,允許用常量來表示特定的資料片斷,而且全部都以型別安全的形式來表示。
常量的使用
在JDK1.5之前,我們定義常量都是:public static fianl....。現在好了,有了列舉,可以把相關的常量分組到一個列舉型別裡,
好處:
列舉型別是Java 5中新增特性的一部分,它是一種特殊的資料型別,之所以特殊是因為它既是一種類(class)型別卻又比類型別多了些特殊的約束,但是這些約束的存在也造就了列舉型別的簡潔性、安全性以及便捷性。
語法解析
1 最最最簡單版
public enum ColorEnum {
RED,BLUE,GREEN
}
通過工具解析class後獲得的原始碼(工具參考上面的連結)
public final class ColorEnum extends Enum { //返回儲存列舉例項的陣列的副本。values()方法通常用於foreach迴圈遍歷列舉常量。 public static ColorEnum[] values() { return (ColorEnum[])$VALUES.clone(); } //根據例項名獲取例項 public static ColorEnum valueOf(String s) { return (ColorEnum)Enum.valueOf(ColorEnum, s); } //私有構造方法,這裡呼叫了父類的構造方法,其中引數s對應了常量名,引數i代表列舉的一個順序(這個順序與列舉的宣告順序對應,用於oridinal()方法返回順序值) private ColorEnum(String s, int i) { super(s, i); } //我們定義的列舉在這裡聲明瞭三個 ColorEnum的常量物件引用,物件的例項化在static靜態塊中 public static final ColorEnum RED; public static final ColorEnum BLUE; public static final ColorEnum GREEN; //將所有列舉的例項存放在陣列中 private static final ColorEnum $VALUES[]; static { RED = new ColorEnum("RED", 0); BLUE = new ColorEnum("BLUE", 1); GREEN = new ColorEnum("GREEN", 2); //將所有列舉的例項存放在陣列中 $VALUES = (new ColorEnum[] { RED, BLUE, GREEN }); } }
自定義函式
package com;
public enum Color { RED("紅色", 1), GREEN("綠色", 2), BLANK("白色", 3), YELLO("黃色", 4); private String name ; private int index ; private Color( String name , int index ){ this.name = name ; this.index = index ; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getIndex() { return index; } public void setIndex(int index) { this.index = index; } }
列舉的好處以及與常量類的區別
1)列舉型可以直接與資料庫打交道,我通常使用varchar型別儲存,對應的是列舉的常量名。(資料庫中好像也有列舉型別,不過也沒用過)
2) switch語句支援列舉型,當switch使用int、String型別時,由於值的不穩定性往往會有越界的現象,對於這個的處理往往只能通過if條件篩選以及default模組來處理。而使用列舉型後,在編譯期間限定型別,不允許發生越界的情況
3) 當你使用常量類時,往往得通過equals去判斷兩者是否相等,使用列舉的話由於常量值地址唯一,可以用==直接對比,效能會有提高
4) 常量類編譯時,是直接把常量的值編譯到類的二進位制程式碼裡,常量的值在升級中變化後,需要重新編譯引用常量的類,因為裡面存的是舊值。列舉類編譯時,沒有把常量值編譯到程式碼裡,即使常量的值發生變化,也不會影響引用常量的類。
5)列舉類編譯後預設為final class,不允許繼承可防止被子類修改。常量類可被繼承修改、增加欄位等,容易導致父類的不相容。
values()獲取儲存列舉中所有常量例項的陣列。常配合foreach完成遍歷
for( Color color : Color.values()){
System.out.println( color + " name: " + color.getName() + " index: " + color.getIndex() );
}
獲取某一實例的值
System.out.println( Color.RED.getName() );
valueOf()通過常量名獲取對應的列舉例項。
ColorEnum red = ColorEnum.valueOf("RED");
getEnumConstants()方法,同樣可以輕而易舉地獲取所有列舉例項變數
Class<?> clasz = e.getDeclaringClass();
if(clasz.isEnum()) {
Day[] dsz = (Day[]) clasz.getEnumConstants();
System.out.println("dsz:"+Arrays.toString(dsz));
}
enumConstantDirectory方法獲取到的是一個Map集合,在該集合中存放了以列舉name為key和以列舉例項變數為value的Key&Value資料
T result = enumType.enumConstantDirectory().get(name);
//建立一個具有指定鍵型別的空列舉對映。
EnumMap(Class<K> keyType)
//建立一個其鍵型別與指定列舉對映相同的列舉對映,最初包含相同的對映關係(如果有的話)。
EnumMap(EnumMap<K,? extends V> m)
//建立一個列舉對映,從指定對映對其初始化。
EnumMap(Map<K,? extends V> m)
//使用第一種構造
Map<Color,Integer> enumMap=new EnumMap<>(Color.class);
//使用第二種構造
Map<Color,Integer> enumMap2=new EnumMap<>(enumMap);
//使用第三種構造
Map<Color,Integer> hashMap = new HashMap<>();
hashMap.put(Color.GREEN, 2);
hashMap.put(Color.BLUE, 3);
Map<Color, Integer> enumMap = new EnumMap<>(hashMap);
EnumMap繼承了AbstractMap類,因此EnumMap具備一般map的使用方法,keyType表示型別資訊,keyUniverse表示鍵陣列,儲存的是所有可能的列舉值,vals陣列表示鍵對應的值,size表示鍵值對個數。在建構函式中通過keyUniverse = getKeyUniverse(keyType);初始化了keyUniverse陣列的值,內部儲存的是所有可能的列舉值,接著初始化了存在Value值得陣列vals,其大小與列舉例項的個數相同,getKeyUniverse方法實現如下
EnumSet是與列舉型別一起使用的專用 Set 集合,EnumSet 中所有元素都必須是列舉型別。與其他Set介面的實現類HashSet/TreeSet(內部都是用對應的HashMap/TreeMap實現的)不同的是,EnumSet在內部實現是位向量(稍後分析)
建立一個具有指定元素型別的空EnumSet。
EnumSet<E> noneOf(Class<E> elementType)
//建立一個指定元素型別幷包含所有列舉值的EnumSet
<E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType)
// 建立一個包括列舉值中指定範圍元素的EnumSet
<E extends Enum<E>> EnumSet<E> range(E from, E to)
// 初始集合包括指定集合的補集
<E extends Enum<E>> EnumSet<E> complementOf(EnumSet<E> s)
// 建立一個包括引數中所有元素的EnumSet
<E extends Enum<E>> EnumSet<E> of(E e)
<E extends Enum<E>> EnumSet<E> of(E e1, E e2)
<E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3)
<E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4)
<E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4, E e5)
<E extends Enum<E>> EnumSet<E> of(E first, E... rest)
//建立一個包含引數容器中的所有元素的EnumSet
<E extends Enum<E>> EnumSet<E> copyOf(EnumSet<E> s)
<E extends Enum<E>> EnumSet<E> copyOf(Collection<E> c)
版權宣告:本文為博主原創文章,轉載請附上博文連結!
---------------------
轉載地址:https://blog.csdn.net/javazejian/article/details/71333103