枚舉


枚舉

枚舉是一個小功能,但是卻帶來了大方便。一個星期有七天,我們平時定義這七天為常量的時候,會這么寫:

public final static String SUNDAY = "0";
public final static String MONDAY = "1";
public final static String TUESDAY = "2";
public final static String WEDNESDAY = "3";
public final static String THRUSDAY = "4";
public final static String FRIDAY = "5";
public final static String SATURDAY = "6";

有了枚舉之后,就可以換一種寫法了:

public enum EnumDay
{
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THRUSDAY, FRIDAY, SATURDAY;
}

這就定義了SUNDAY~SATURDAY的枚舉了,使用枚舉類型代替了常量,還提供了比常量更多的方法。枚舉類型適用的數據有以下特點:

1、枚舉值之間是有內在關聯的,比如上面的,都是一個星期的七天

2、常量的值是隨便的,比如SUNDAY必須是"12345",MONDAY必須是"23456"也可以用枚舉,不過要麻煩些

上面的EnumDay其實隱含了所創建的類型都是java.lang.Enum類的子類,枚舉類型符合通用模式Class Enum<E extends Enum<E>>,E表示的就是枚舉類型的名稱。枚舉類型的每一個值都將映射到protected Enum<String name, int ordinal>構造函數中,在這里,每個值的名稱都被轉換為一個字符串,並且序數設置表示了此設置被創建的順序。EnumDay實際調用了7此Enum:

new Enum<EnumDay>("SUNDAY", 0);
new Enum<EnumDay>("MONDAY", 1);
new Enum<EnumDay>("TUESDAY", 2);
new Enum<EnumDay>("WEDNESDAY", 3);
new Enum<EnumDay>("THRUSDAY", 4);
new Enum<EnumDay>("FRIDAY", 5);
new Enum<EnumDay>("SATURDAY", 6);

所以,只要記住每個枚舉值都是一個泛型為EnumDay的Enum就可以了。

 

遍歷枚舉類型及枚舉方法

既然知道了枚舉類型里面的枚舉值都是一個Enum<EnumDay>,那就好辦了,可以查看JDK API來看下Enum里面有哪些方法並使用下,看一下例子:

public static void main(String[] args) throws Exception
{
    EnumDay[] eds = EnumDay.values(); // 將EnumDay中的枚舉值轉換為EnumDay數組
    int i = 0;
    for (EnumDay ed : eds)
    {
        System.out.println("EnumDay[" + i + "]:" + ed.toString()); // 返回枚舉常量的名稱
        i++;
    }
    System.out.println();
        
    System.out.println("Enum<EnumDay>.compareTo():" + eds[0].compareTo(eds[1])); // 比較此枚舉與指定枚舉的順序,被比較對象小於、等於、大於比較對象時,分別返回負整數、0、正整數,只能和相同枚舉類型相比較
    System.out.println("Enum<EnumDay>.equals():" + eds[0].equals(eds[1])); // 比較指定兩個枚舉類型是否相同
    System.out.println("Enum<EnumDay>.getDeclaringClass():" + eds[0].getDeclaringClass()); // 獲取指定枚舉值的枚舉類型對應的Class對象
    System.out.println("Enum<EnumDay>.hashCode():" + eds[0].hashCode()); // 獲取指定枚舉值對應的hashCode
    System.out.println("Enum<EnumDay>.name():" + eds[0].name()); // 獲取指定枚舉值的名稱
    System.out.println("Enum<EnumDay>.ordinal():" + eds[0].ordinal()); // 獲取指定枚舉值對應的序數
}

結果為:

EnumDay[0]:SUNDAY
EnumDay[1]:MONDAY
EnumDay[2]:TUESDAY
EnumDay[3]:WEDNESDAY
EnumDay[4]:THRUSDAY
EnumDay[5]:FRIDAY
EnumDay[6]:SATURDAY

Enum<EnumDay>.compareTo():-1
Enum<EnumDay>.equals():false
Enum<EnumDay>.getDeclaringClass():class com.xrq.test37.EnumDay
Enum<EnumDay>.hashCode():1414159026
Enum<EnumDay>.name():SUNDAY
Enum<EnumDay>.ordinal():0

看到toString()方法和name()方法的值是一樣,可能有人會想,那要這兩個方法干嘛?toString()方法這里因為沒有重寫,實際上這個方法被開發者重寫之后,就打印出了開發者需要的內容了,沒有重寫toString()方法打印的就是name屬性了,看一下Enum類的源代碼就知道了。

 

為枚舉類型中的枚舉值定義數值----自定義屬性和方法

不給枚舉類型中的枚舉值定義數值,那么數值是從0開始逐個加上去的,當然我們也可以給枚舉類型中的枚舉值自定義數值,這時就要在EnumDay里面自定義屬性和方法了:

public enum EnumDay
{
    SUNDAY(1234), MONDAY(2345), TUESDAY(3456), WEDNESDAY(4567), THRUSDAY(5678), FRIDAY(6789), SATURDAY(7890)
    {
        public String toString()
        {
            return super.toString();
        }
    };
    
    private int value;
    
    private EnumDay(int value)
    {
        this.value = value;
    }
    
    public int getValue()
    {
        return value;
    }
}

main函數可以直接調用getValue()方法,因為每個枚舉值都是一個EnumDay:

public static void main(String[] args)
{
    EnumDay[] eds = EnumDay.values();
    for (EnumDay ed : eds)
    {
        System.out.println(ed.name() + ":" + ed.getValue());
    }
}

運行結果為:

SUNDAY:1234
MONDAY:2345
TUESDAY:3456
WEDNESDAY:4567
THRUSDAY:5678
FRIDAY:6789
SATURDAY:7890

從例子中看到,可以為枚舉類型自定義方法,也可以自定義屬性,也可以重寫父類中的方法(如果不自定義方法的話,只有toString()方法可以重寫,因為只有它不是final的),枚舉類型是Enum<E extends Enum<E>>,所以EnumDay也可以繼承類,實現接口,定義更多的方法。

 

EnumSet、EnumMap

EnumSet和EnumMap是分別為枚舉類型定制的Set和Map,看一下它們的用法:

public static void main(String[] args)
{
    EnumSet<EnumDay> es = EnumSet.allOf(EnumDay.class);
    for (EnumDay ed : es)
        System.out.println(ed.name() + ":" + ed.ordinal());
        
    System.out.println("\n-----EnumSet和EnumMap之間的分隔線-----\n");
        
    EnumMap<EnumDay, String> em = new EnumMap<EnumDay, String>(EnumDay.class);
    em.put(EnumDay.SUNDAY, "星期天");
    em.put(EnumDay.MONDAY, "星期一");
    em.put(EnumDay.TUESDAY, "星期二");
    em.put(EnumDay.WEDNESDAY, "星期三");
    em.put(EnumDay.THRUSDAY, "星期四");
    em.put(EnumDay.FRIDAY, "星期五");
    em.put(EnumDay.SATURDAY, "星期六");
        
    Iterator<Entry<EnumDay, String>> iterator = em.entrySet().iterator();
    while (iterator.hasNext())
    {
        Entry<EnumDay, String> entry = iterator.next();
        System.out.println(entry.getKey().name() + ":" + entry.getValue());
    }
}

運行結果為:

SUNDAY:0
MONDAY:1
TUESDAY:2
WEDNESDAY:3
THRUSDAY:4
FRIDAY:5
SATURDAY:6

-----EnumSet和EnumMap之間的分隔線-----

SUNDAY:星期天
MONDAY:星期一
TUESDAY:星期二
WEDNESDAY:星期三
THRUSDAY:星期四
FRIDAY:星期五
SATURDAY:星期六

注意一下EnumSet和EnumMap都是線程非安全的。


免責聲明!

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



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