枚举
1.枚举的用法及使用场景
在实际编程中,往往存在着这样的“数据集”,它们的数值在程序中是稳定的,而且“数据集”中的元素是有限的。
例如星期一到星期日七个数据元素组成了一周的“数据集”,春夏秋冬四个数据元素组成了四季的“数据集”。
在java中如何更好的使用这些“数据集”呢?因此枚举便派上了用场,以下代码详细介绍了枚举的用法。
package basicExercises
;
public class test {
// 普通枚举
public enum ColorEnum {
red , green , yellow , blue ;
}
// 枚举像普通的类一样可以添加属性和方法,可以为它添加静态和非静态的属性或方法
public enum SeasonEnum {
// 注:枚举写在最前面,否则编译出错
spring , summer , autumn , winter ;
private final static String position = "test" ;
public static SeasonEnum getSeason() {
if ( "test".equals( position)) // 编译后是 "test".equals(test)
return spring ;
else
return winter ;
}
}
// 性别 : 实现带有构造器的枚举
public enum Gender{
// 通过括号赋值 , 而且必须带有一个参构造器和一个属性跟方法,否则编译出错
// 赋值必须都赋值或都不赋值,不能一部分赋值一部分不赋值;如果不赋值则不能写构造器,赋值编译也出错
MAN( "MAN") , WOMEN( "WOMEN") ;
private final String value ;
// 构造器默认也只能是 private, 从而保证构造函数只能在内部使用
Gender(String value) {
this. value = value ;
}
public String getValue() {
return value ;
}
}
// 订单状态 : 实现带有抽象方法的枚举
public enum OrderState {
CANCEL { public String getName(){ return " 已取消 " ;}} ,
WAITCONFIRM { public String getName(){ return " 待审核 " ;}} ,
WAITPAYMENT { public String getName(){ return " 等待付款 " ;}} ,
ADMEASUREPRODUCT { public String getName(){ return " 正在配货 " ;}} ,
WAITDELIVER { public String getName(){ return " 等待发货 " ;}} ,
DELIVERED { public String getName(){ return " 已发货 " ;}} ,
RECEIVED { public String getName(){ return " 已收货 " ;}} ;
public abstract String getName() ;
}
public static void main(String[] args) {
// 枚举是一种类型,用于定义变量,以限制变量的赋值;赋值时通过 “ 枚举名 . 值 ” 取得枚举中的值
ColorEnum colorEnum = ColorEnum. blue ;
switch (colorEnum) {
case red:
System. out.println( "color is red") ;
break;
case green:
System. out.println( "color is green") ;
break;
case yellow:
System. out.println( "color is yellow") ;
break;
case blue:
System. out.println( "color is blue") ;
break;
}
// 遍历枚举
System. out.println( " 遍历 ColorEnum 枚举中的值 ") ;
for(ColorEnum color : ColorEnum. values()){
System. out.println(color) ;
}
// 获取枚举的个数
System. out.println( "ColorEnum 枚举中的值有 "+ColorEnum. values(). length+ " 个 ") ;
// 获取枚举的索引位置,默认从 0 开始
System. out.println(ColorEnum. red.ordinal()) ; //0
System. out.println(ColorEnum. green.ordinal()) ; //1
System. out.println(ColorEnum. yellow.ordinal()) ; //2
System. out.println(ColorEnum. blue.ordinal()) ; //3
// 枚举默认实现了 java.lang.Comparable 接口
System. out.println(ColorEnum. red.compareTo(ColorEnum. green)) ; //-1
//--------------------------
System. out.println( "===========") ;
System. err.println( " 季节为 " + SeasonEnum. getSeason()) ;
//--------------
System. out.println( "===========") ;
for(Gender gender : Gender. values()){
System. out.println(gender. value) ;
}
//--------------
System. out.println( "===========") ;
for(OrderState order : OrderState. values()){
System. out.println(order.getName()) ;
}
}
}
public class test {
// 普通枚举
public enum ColorEnum {
red , green , yellow , blue ;
}
// 枚举像普通的类一样可以添加属性和方法,可以为它添加静态和非静态的属性或方法
public enum SeasonEnum {
// 注:枚举写在最前面,否则编译出错
spring , summer , autumn , winter ;
private final static String position = "test" ;
public static SeasonEnum getSeason() {
if ( "test".equals( position)) // 编译后是 "test".equals(test)
return spring ;
else
return winter ;
}
}
// 性别 : 实现带有构造器的枚举
public enum Gender{
// 通过括号赋值 , 而且必须带有一个参构造器和一个属性跟方法,否则编译出错
// 赋值必须都赋值或都不赋值,不能一部分赋值一部分不赋值;如果不赋值则不能写构造器,赋值编译也出错
MAN( "MAN") , WOMEN( "WOMEN") ;
private final String value ;
// 构造器默认也只能是 private, 从而保证构造函数只能在内部使用
Gender(String value) {
this. value = value ;
}
public String getValue() {
return value ;
}
}
// 订单状态 : 实现带有抽象方法的枚举
public enum OrderState {
CANCEL { public String getName(){ return " 已取消 " ;}} ,
WAITCONFIRM { public String getName(){ return " 待审核 " ;}} ,
WAITPAYMENT { public String getName(){ return " 等待付款 " ;}} ,
ADMEASUREPRODUCT { public String getName(){ return " 正在配货 " ;}} ,
WAITDELIVER { public String getName(){ return " 等待发货 " ;}} ,
DELIVERED { public String getName(){ return " 已发货 " ;}} ,
RECEIVED { public String getName(){ return " 已收货 " ;}} ;
public abstract String getName() ;
}
public static void main(String[] args) {
// 枚举是一种类型,用于定义变量,以限制变量的赋值;赋值时通过 “ 枚举名 . 值 ” 取得枚举中的值
ColorEnum colorEnum = ColorEnum. blue ;
switch (colorEnum) {
case red:
System. out.println( "color is red") ;
break;
case green:
System. out.println( "color is green") ;
break;
case yellow:
System. out.println( "color is yellow") ;
break;
case blue:
System. out.println( "color is blue") ;
break;
}
// 遍历枚举
System. out.println( " 遍历 ColorEnum 枚举中的值 ") ;
for(ColorEnum color : ColorEnum. values()){
System. out.println(color) ;
}
// 获取枚举的个数
System. out.println( "ColorEnum 枚举中的值有 "+ColorEnum. values(). length+ " 个 ") ;
// 获取枚举的索引位置,默认从 0 开始
System. out.println(ColorEnum. red.ordinal()) ; //0
System. out.println(ColorEnum. green.ordinal()) ; //1
System. out.println(ColorEnum. yellow.ordinal()) ; //2
System. out.println(ColorEnum. blue.ordinal()) ; //3
// 枚举默认实现了 java.lang.Comparable 接口
System. out.println(ColorEnum. red.compareTo(ColorEnum. green)) ; //-1
//--------------------------
System. out.println( "===========") ;
System. err.println( " 季节为 " + SeasonEnum. getSeason()) ;
//--------------
System. out.println( "===========") ;
for(Gender gender : Gender. values()){
System. out.println(gender. value) ;
}
//--------------
System. out.println( "===========") ;
for(OrderState order : OrderState. values()){
System. out.println(order.getName()) ;
}
}
}
//运行结果
color is blue
季节为spring
遍历ColorEnum枚举中的值
red
green
yellow
blue
ColorEnum枚举中的值有4个
0
1
2
3
-1
===========
===========
MAN
WOMEN
===========
已取消
待审核
等待付款
正在配货
等待发货
已发货
已收货
2.枚举用法举例
用法一:常量
- public enum Color {
- RED, GREEN, BLANK, YELLOW
- }
用法二:switch
- enum Signal {
- GREEN, YELLOW, RED
- }
- public class TrafficLight {
- Signal color = Signal.RED;
- public void change() {
- switch (color) {
- case RED:
- color = Signal.GREEN;
- break;
- case YELLOW:
- color = Signal.RED;
- break;
- case GREEN:
- color = Signal.YELLOW;
- break;
- }
- }
- }
用法三:向枚举中添加新方法
如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。而且
Java 要求必须先定义
enum 实例。
- 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 static String getName(int index) {
- for (Color c : Color.values()) {
- if (c.getIndex() == index) {
- return c.name;
- }
- }
- return null;
- }
- // get set 方法
- 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;
- }
- }
用法四:覆盖枚举的方法
- 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;
- }
- //覆盖方法
- @Override
- public String toString() {
- return this.index+"_"+this.name;
- }
- }
用法五:实现接口
所有的枚举都继承自java.lang.Enum类。由于
Java 不支持多继承,所以枚举对象不能再继承其他类。
- public interface Behaviour {
- void print();
- String getInfo();
- }
- public enum Color implements Behaviour{
- 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;
- }
- //接口方法
- @Override
- public String getInfo() {
- return this.name;
- }
- //接口方法
- @Override
- public void print() {
- System.out.println(this.index+":"+this.name);
- }
- }
用法六:使用接口组织枚举
Java代码
- public interface Food {
- enum Coffee implements Food{
- BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO
- }
- enum Dessert implements Food{
- FRUIT, CAKE, GELATO
- }
- }
用法七:关于枚举集合的使用
java.util.EnumSet和java.util.EnumMap是两个枚举集合。
EnumSet保证集合中的元素不重复;
EnumMap中的 key是enum类型,而value则可以是任意类型。
private
static
void
testEnumMap() {
//
1.演示定义EnumMap对象,EnumMap对象的构造函数需要参数传入,默认是key的类的类型
EnumMap<Light, String> currEnumMap =
new EnumMap<Light, String>
(Light.
class);
currEnumMap.put(Light.RED, "红灯"
);
currEnumMap.put(Light.GREEN, "绿灯"
);
currEnumMap.put(Light.YELLOW, "黄灯"
);
//
2.遍历对象
for
(Light aLight : Light.values()) {
System.out.println("[key=" + aLight.name() + ",value=" + currEnumMap.get(aLight) + "]");
}
}
3.分析总结:
enum 的语法结构尽管和 class 的语法不一样,但是经过编译器编译之后产生的是一个class文件。
该class文件经过反编译可以看到实际上是生成了一个类,该类继承了java.lang.Enum<E>。
EnumTest 经过反编译(javap com.hmw.test.EnumTest 命令)之后得到的内容如下:
public
class
com.hmw.test.EnumTest
extends
java.lang.Enum{
public
static
final
com.hmw.test.EnumTest MON;
public
static
final
com.hmw.test.EnumTest TUE;
public
static
final
com.hmw.test.EnumTest WED;
public
static
final
com.hmw.test.EnumTest THU;
public
static
final
com.hmw.test.EnumTest FRI;
public
static
final
com.hmw.test.EnumTest SAT;
public
static
final
com.hmw.test.EnumTest SUN;
static
{};
public
int
getValue();
public
boolean
isRest();
public
static
com.hmw.test.EnumTest[] values();
public
static
com.hmw.test.EnumTest valueOf(java.lang.String);
com.hmw.test.EnumTest(java.lang.String,
int
,
int
, com.hmw.test.EnumTest);
}
|
可以把 enum 看成是一个普通的 class,它们都可以定义一些属性和方法,不同之处是:enum 不能使用 extends 关键字继承其他类,因为 enum 已经继承了 java.lang.Enum(java是单一继承)。