JAVA枚举.docx
《JAVA枚举.docx》由会员分享,可在线阅读,更多相关《JAVA枚举.docx(20页珍藏版)》请在冰豆网上搜索。
JAVA枚举
一、使用简单程序完成枚举的功能
例:
使用简单类完成枚举操作
classColor{
publicstaticfinalColorRED=newColor("红色");//定义第一个对象
publicstaticfinalColorGREEN=newColor("绿色");//定义第二个对象
publicstaticfinalColorBLUE=newColor("蓝色");//定义第三个对象
privateStringname;
privateColor(Stringname){//构造方法私有化,同时设置颜色的名称
this.setName(name);//为颜色的名字赋值
}
publicStringgetName(){//取得颜色名称
returnthis.name;
}
publicvoidsetName(Stringname){//设置颜色名称
this.name=name;
}
publicstaticColorgetInstance(inti){//得到一个颜色,只能从固定的几个颜色中取得
switch(i){
case1:
{ //返回红色对象
returnRED;
}
case2:
{ //返回绿色对象
returnGREEN;
}
case3:
{ //返回蓝色对象
returnBLUE;
}
default:
{ //错误的值
returnnull;
}
}
}
}
publicclassColorDemo{
publicstaticvoidmain(Stringargs[]){
Colorc1=Color.RED; //取得红色
System.out.println(c1.getName());//输出名字
Colorc2=Color.getInstance(3);//根据编号取得名字
System.out.println(c2.getName());//输出名字
}
}
输出:
红色
蓝色
程序将Color类中的构造方法私有,之后在类中准备了若干个实例化对象,以后如果要取得
Color类的实例,则只能从RED、GREEN、BLUE3个对象中取得,这样就有效地限制了对象的
取得范围。
以上使用的Color对象指定的范围,是通过一个个常量对每个对象进行编号的。
也就是说,
一个个的对象就相当于用常量表示了,所以,按照这个思路也可以直接使用一个接口规定
出一组常量的范围。
例:
使用接口表示一组范围。
publicinterfaceColor{
publicstaticfinalintRED=1;//表示红色
publicstaticfinalintGREEN=2;//表示绿色
publicstaticfinalintBLUE=3;//表示蓝色
}
以上表示出的各个颜色是通过接口指定好的常量范围,与之前相比更加简单。
但是这样做也会
存在另外一个问题,如果现在使用如下的代码:
publicclassColorDemo{
publicstaticvoidmain(Stringargs[]){
System.out.println(Color.RED+Color.GREEN);//颜色相加
}
}
输出:
3
两个颜色的常量相加后形成“3”,这样的结果看起来会令人很困惑,操作很不明确。
二、定义一个枚举类型
例:
定义一个Color的枚举类型
publicenumColor{ //定义枚举类型
RED,GREEN,BLUE;//定义枚举的3个类型
}
以上的Color定义出来的枚举类型,其中包含RED,GREEN,BLUE3个数据。
可以使用“枚举.variable”的形式
取出枚举中的指定内容。
例:
取出一个枚举的内容
publicclassGetEnumContent{
publicstaticvoidmain(Stringargs[]){
Colorc=Color.BLUE;//取出蓝色
System.out.println(c);//输出信息
}
}
输出:
BLUE
枚举类型的数据也可以使用“枚举.values()”的形式,将全部的枚举类型变为对象数组的形式
,之后直接使用foreach进行输出。
例:
使用foreach输出枚举内容
publicclassPrintDemo{
publicstaticvoidmain(Stringargs[]){
for(Colorc:
Color.values()){ //枚举.values()表示得到全部枚举的内容
System.out.println(c);
}
}
}
输出:
RED
GREEN
BLUE
枚举中的每个类型也可以使用switch进行判断,但在switch语句中使用枚举类型时,一定
不能在每一个枚举类型值的前面加上枚举类型的类名(如Color.BlUE),否则编译器将会报错。
例:
使用switch进行判断
publicclassSwitchPrintDemo{
publicstaticvoidmain(Stringargs[]){
for(Colorc:
Color.values()){ //枚举.values()表示得到全部枚举的内容
print(c);
}
}
publicstaticvoidprint(Colorcolor){
switch(color){ //判断每个颜色
caseRED:
{ //直接判断枚举内容
System.out.println("红颜色");
break;
}
caseGREEN:
{ //直接判断枚举内容
System.out.println("绿颜色");
break;
}
caseBLUE:
{ //直接判断枚举内容
System.out.println("蓝颜色");
break;
}
default:
{ //未知内容
System.out.println("未知颜色");
break;
}
}
}
}
输出:
红颜色
绿颜色
蓝颜色
上面的Color.values()方法表示取得枚举中的全部内容,返回的是一个对象数组,这是枚举本身支持的一个方法,除了这个方法之外到底还有
哪些方法可以供开发者使用呢?
三、Enum
使用Enum关键字定义一个枚举,实际上此关键字表示的是java.lang.Enum类型,即使用enum
声明的枚举类型就相当于定义一个类,而此类则默认继承java.lang.Enum类。
java.lang.Enum类的定义如下:
publicabstractclassEnum>
extendsObject
implementsComparable,Serializable
从Enum类的定义中可以清楚地发现,此类实现了Comparable和Serializable两个接口,证明
枚举类型可以使用比较器和序列化操作。
枚举类的主要操作方法
protectedEnum(Stringname,intordinal)
构造接收枚举的名称和枚举的常量创建枚举对象
protectedfinalObjectclone()throwsCloneNotSupportedException
克隆枚举对象
publicfinalintcompareTo(Eo)
对象比较
publicfinalbooleanequals(Objectother)
比较两个枚举对象
publicfinalinthashCode()
返回枚举常量的哈希码
publicfinalStringname()
返回此枚举的名称
publicfinalintordinal()
返回枚举常量的序数
publicstatic>TvalueOf(ClassenumType,Stringname)
返回带指定名称的指定枚举类型的枚举常量
取得枚举的信息
在枚举建立完成之后,实际上都会调用枚举类中的构造方法,为其赋值。
在Enum类的构造
方法中的第一个参数name就是定义的枚举的名称,第二个参数ordinal则会从0开始依次进行
编号。
之后可以使用Enum类中的name()和ordinal()方法取得名称和编号。
例:
验证name()和ordinal()方法
enumColor{ //定义枚举类型
RED,GREEN,BLUE;//定义枚举的3个类型
}
publicclassGetEnumInfo{
publicstaticvoidmain(Stringargs[]){
for(Colorc:
Color.values()){
//枚举.values()表示得到全部枚举的内容
System.out.println(c.ordinal()+"-->"+c.name());
}
}
}
输出:
0-->RED
1-->GREEN
2-->BLUE
从结果中发现Enum类自动为枚举中的每个元素进行编号,而且下标从0开始。
四、为每一个枚举对象属性赋值
1、通过构造方法为属性赋值
每个枚举类中都有其指定好的若干对象,当然,每一个枚举对象中也可以包含多个属性。
而这些属性也可以通过构造方法为其赋值。
例:
通过构造方法为枚举属性赋值
enumColor{
RED("红色"),GREEN("绿色"),BLUE("蓝色");
privateColor(Stringname){
this.setName(name);
}
privateStringname;
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
}
publicclassConstructorEnum{
publicstaticvoidmain(Stringargs[]){
for(Colorc:
Color.values()){
System.out.println(c.ordinal()
+"-->"+c.name()
+"("+c.getName()+")");
}
}
}
输出:
0-->RED(红色)
1-->GREEN(绿色)
2-->BLUE(蓝色)
以上程序代码在定义的Color枚举类中设置了一个name属性,并且通过构造方法设置
name属性的内容。
因为Color中已经明确地写出有一个参数的构造方法,所以在声明
枚举内容时就必须调用这个构造方法,这样在定义枚举内容的就必须使用如下语句:
RED("红色"),GREEN("绿色"),BLUE("蓝色");
2、通过setter方法为属性赋值
以上是通过构造方法的方式为属性赋值的,当然也可以通过调用setter()的方式为指定
的属性赋值。
但是这样一来就必须明确每一个枚举类的对象,如果操作的对象是RED,则
名字应该为“红色”;如果操作的是GREEN,则名字应该为“绿色”等。
例:
使用setName()设置内容
enumColor{
RED,GREEN,BLUE;
privateStringname;
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
switch(this){ //判断是否是紅色
caseRED:
{
if("红色".equals(name)){
this.name=name;
}else{
System.out.println("设置内容错误。
");
}
break;
}
caseGREEN:
{
if("绿色".equals(name)){
this.name=name;
}else{
System.out.println("设置内容错误。
");
}
break;
}
caseBLUE:
{
if("蓝色".equals(name)){
this.name=name;
}else{
System.out.println("设置内容错误。
");
}
break;
}
}
}
}
publicclassSetEnum{
publicstaticvoidmain(Stringargs[]){
Colorc=Color.BLUE;
c.setName("兰色"); //设置一个错误的名字
c.setName("蓝色"); //设置一个正确的名字
System.out.println(c.getName());
}
}
输出:
设置内容错误。
蓝色
以上代码中首先通过枚举取得了一个对象。
之后开始为其设置内容,一开始设置了一个不
符合要求的内容,所以会出现“设置内容错误”的提示;而如果设置的内容正确,则可以
直接将其赋值给name属性。
如果不想通过“枚举类.对象”的形式取得每一个枚举类对象,也可以使用Enum类定义的
“枚举类.valueof()”方法的形式进行调用。
例:
使用valueof()方法找到一个枚举对象。
publicclassValueOfEnum{
publicstaticvoidmain(Stringargs[]){
Colorc=Enum.valueOf(Color.class,"BLUE");
c.setName("兰色"); //设置一个错误的名字
c.setName("蓝色"); //设置一个正确的名字
System.out.println(c.getName());
}
}
输出:
设置内容错误。
蓝色
以上操作代码使用valueof(),但是在设置第一个参数时使用了“枚举.class”的
形式,此为Java的反射机制。
五、使用比较器
在Enum类的定义中已经实现好了Comparable接口,所以枚举类的内容本身是可以进行排序
的,下面通过TreeSet演示枚举的排序操作。
在类集部分曾经介绍过TreeSet可以直接进行排序,排序的规则是通过Comparable接口完成
的。
例:
验证枚举比较器
importjava.util.Iterator;
importjava.util.Set;
importjava.util.TreeSet;
enumColor{
RED,GREEN,BLUE;
}
publicclassComparableEnum{
publicstaticvoidmain(Stringargs[]){
Sett=newTreeSet();
t.add(Color.GREEN);
t.add(Color.BLUE);
t.add(Color.RED);
Iteratoriter=t.iterator();
while(iter.hasNext()){
System.out.print(iter.next()+"、");
}
}
}
输出:
RED、GREEN、BLUE、
以上代码中数据加入的顺序是GREEN、BLUE、RED,但是输出之后的顺序是RED、GREEN、BLUE
证明已经被排序了,是使用Enum类中的ordinal属性排序的。
六、类集对枚举的支持——EnumMap、EnumSet
1、EnumMap
EnumMap是Map接口的子类,所以本身还是以Map的形式进行操作,即key-value。
如果要使用
EnumMap,则首先要创建EnumMap的对象,在创建此对象时必须指定要操作的枚举类型,构造
方法如下:
publicEnumMap(ClasskeyType)
例:
验证EnumMap
importjava.util.EnumMap;
importjava.util.Map;
enumColor{
RED,GREEN,BLUE;
}
publicclassComparableEnum{
publicstaticvoidmain(Stringargs[]){
Mapdesc=null;
desc=newEnumMap(Color.class);
desc.put(Color.RED,"红色");
desc.put(Color.GREEN,"绿色");
desc.put(Color.BLUE,"蓝色");
System.out.println("=====输出全部内容=====");
for(Colorc:
Color.values()){ //取得全部的枚举
System.out.println(c.name()+"-->"+desc.get(c));
}
System.out.println("=====输出全部键值=====");
for(Colorc:
desc.keySet()){ //取得全部的key
System.out.print(c.name()+"、");
}
System.out.println();
System.out.println("=====输出全部的内容=====");
for(Strings:
desc.values()){ //取得全部的value
System.out.print(s+"、");
}
}
}
输出:
=====输出全部内容=====
RED-->红色
GREEN-->绿色
BLUE-->蓝色
=====输出全部键值=====
RED、GREEN、BLUE、
=====输出全部的内容=====
红色、绿色、蓝色、
2、EnumSet
EnumSet是Set接口的子类,所以里面的内容是无法重复的。
使用EnumSet时不能直接使用
关键字new为其进行实例化,所以在此类中提供了很多的静态方法,如表:
publicstatic>EnumSet
allOf(ClasselementType) 将枚举中的全部内容设置到EnumSet中
publicstatic>EnumSet
of(Efirst,E...rest) 创建一个包含枚举指定内容的EnumSet对象
publicstatic>EnumSet
copyOf(Collectionc) 创建一个从指定Collection中指定的EnumSet对象
publicstatic>EnumSet
ComplementOf(EnumSets)
创建一个其元素类型与指定枚举set相同的枚举set,最初包含指定集合中所不包含的此类型的所有元素
publicstatic>EnumSet
noneOf(ClasselementType) 创建一个可以接收指定类的空集合
例:
验证EnumSet——将全部的集合设置到EnumSet集合中
importjava.util.EnumSet;
enumColor{
RED,GREEN,BLUE;
}
publicclassComparableEnum{
publicstaticvoidmain(Stringargs[]){
EnumSetes=null; //声明一个EnumSet对象
System.out.println("====EnumSet.allOf(Color.Class)====");
es=EnumSet.allOf(Color.class);//将枚举的全部类型设置到EnumSet对象中
print(es);
}
publicstaticvoidprint(EnumSettemp){
for(Colorc:
temp){
System.out.print(c+"、");
}
System.out.println();
}
}
输出:
====EnumSet.allOf(Color.Class)====
RED、GREEN、BLUE、
以上程序使用EnumSet提供的static方法allOf(),将一个枚举中的全部内容设置到EnumSet集合中。
例:
验证EnumSet——只设置一个枚举的类型到集合中
importjava.util.EnumSet;
enumColor{
RED,GREEN,BLUE;
}
publicclassComparableEnum{
publicstaticvoidmain(Stringargs[]){
EnumSetes=null; //声明一个EnumSet对象
System.out.println("====EnumSet.al