一、為什么需要枚舉
舉個(gè)例子程梦,生物界性別分“雄性”点把、“雌性”和“中性”,將其定義為靜態(tài)常量:
public class Gender{
public static final int Male = 1;
public static final int Female = 2;
public static final int Neutral = 3;
}
對(duì)于這種單值類(lèi)型的靜態(tài)常量定義屿附,本身也沒(méi)錯(cuò)郎逃,主要是在使用的地方?jīng)]有一個(gè)明確性的約束而已,比如這里的 judgeGender 方法的本意是傳入 Gender 的三種靜態(tài)常量之一挺份,但由于沒(méi)有類(lèi)型上的約束褒翰,因此傳入任意一個(gè) int 值都是可以的,編譯器也不會(huì)提出任何警告。
void judgeGender(int code){}
但是在枚舉類(lèi)型出現(xiàn)之后优训,上面這種情況就可以用枚舉嚴(yán)謹(jǐn)?shù)厝ゼs束朵你,比如用枚舉去定義性別就非常簡(jiǎn)潔了:
public enum Gender {
Male, Female, Neutral
}
而且主要是在用枚舉的地方會(huì)有更強(qiáng)的類(lèi)型約束。如下入?yún)㈩?lèi)型就會(huì)受到明確的類(lèi)型約束揣非,一旦傳入無(wú)效值抡医,編譯器就會(huì)幫檢查,從而規(guī)避潛在問(wèn)題早敬。除此之外魂拦,枚舉在擴(kuò)展性方面比普通常量更方便、也更優(yōu)雅搁嗓。
//入?yún)⒕拖薅祟?lèi)型
void judgeGender(Gender gender){}
綜上芯勘,枚舉的意義:
1??封裝有限的變化,提高代碼維護(hù)性腺逛,確保變量合法荷愕。
如果利用 int 類(lèi)型表示星期一到星期日的話,就要判斷輸入 int 變量不在 1-7 的范圍內(nèi)的情況棍矛。
2??代碼更優(yōu)雅安疗,提高代碼可讀性。一個(gè)復(fù)制的程序里面够委,可能要用到成百上千的靜態(tài)常量荐类,如果全寫(xiě)在一個(gè)文件里面,容易造成命名混淆茁帽,程序讀起來(lái)也比較麻煩玉罐。
二、單值枚舉
定義一個(gè)性別枚舉:
public enum Gender {
Male, Female, Neutral
}
枚舉的所有基本用法:
public class judgeGender {
public static void main(String[] args) {
for (Gender genderType : Gender.values()) {
System.out.println(genderType);
}
Gender male = Gender.Male;
Gender female = Gender.Female;
Gender neutral = Gender.Neutral;
System.out.println(male.ordinal());//0
System.out.println(female.ordinal());//1
System.out.println(neutral.ordinal());//2
System.out.println(male.name());//Male
System.out.println(female.name());//Female
System.out.println(neutral.name());//Neutral
System.out.println(male.compareTo(male));//0
System.out.println(male.compareTo(female));//-1
System.out.println(female.compareTo(neutral));//-1
System.out.println(Gender.valueOf("Male"));//Male
System.out.println(Gender.valueOf("Female"));//Female
System.out.println(Gender.valueOf("Neutral"));//Neutral
Gender gender = Gender.Male;
switch (gender) {
case Male:
System.out.println("男");
break;
case Female:
System.out.println("女");
break;
case Neutral:
System.out.println("中性");
break;
}//男
}
}
三潘拨、多值枚舉
上面展示的枚舉例子非常簡(jiǎn)單吊输,僅僅是單值的情形,而實(shí)際項(xiàng)目中用枚舉往往是多值用法铁追。擴(kuò)充一下上面的 Gender 枚舉季蚂,在里面加入 【說(shuō)明 -- 編碼】的對(duì)應(yīng)關(guān)系,這也是實(shí)際項(xiàng)目中常用的用法琅束∨てǎ可以在枚舉里自定義各種屬性、構(gòu)造函數(shù)涩禀、甚至各種方法:
public enum GenterType {
Male("男", "01"),
Female("女", "02"),
Neutral("中性", "03"),
;
//自定義屬性
private final String explain;
private final String code;
public String getExplain() {
return explain;
}
public String getCode() {
return code;
}
//自定義構(gòu)造函數(shù)
GenterType(String explain, String code) {
this.explain = explain;
this.code = code;
}
}
從上述代碼可知料滥,在 enum 枚舉類(lèi)中完全可以像在普通 Class 里一樣聲明屬性、構(gòu)造函數(shù)以及成員方法埋泵。
四幔欧、專(zhuān)門(mén)用于枚舉的集合類(lèi)
一般習(xí)慣于使用諸如:HashMap 和 HashSet 等集合來(lái)盛放元素罪治。而對(duì)于枚舉,有專(zhuān)門(mén)的集合類(lèi): EnumSet 和 EnumMap
1??EnumSet
EnumSet 是專(zhuān)門(mén)為盛放枚舉類(lèi)型所設(shè)計(jì)的 Set 類(lèi)型礁蔗。
2??EnumMap
EnumMap 則是用來(lái)專(zhuān)門(mén)盛放枚舉類(lèi)型為 key 的 Map 類(lèi)型觉义。