1. 程式人生 > >java列舉初學習

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