一:Enum 类型的介绍
枚举类型(Enumerated Type) 很早就出现在编程语言中,它被用来将一组类似的值包含到一种类型当中。而这种枚举类型的名称则会被定义成独一无二的类型描述符,在这一点上和常量的定义相似。不过相比较常量类型,枚举类型可以为申明的变量提供更大的取值范围。
二:Enum 类型的特点
- 在某些情况下,一个类的对象时有限且固定的,如季节类,它只有春夏秋冬4个对象这种实例有限且固定的类,在 Java 中被称为枚举类;
- 在 Java 中使用 enum 关键字来定义枚举类,其地位与 class、interface 相同;
- 枚举类是一种特殊的类,它和普通的类一样,有自己的成员变量、成员方法、构造器 (只能使用 private 访问修饰符,所以无法从外部调用构造器,构造器只在构造枚举值时被调用);
- 一个 Java 源文件中最多只能有一个 public 类型的枚举类,且该 Java 源文件的名字也必须和该枚举类的类名相同,这点和类是相同的;
- 使用 enum 定义的枚举类默认继承了 java.lang.Enum 类,并实现了 java.lang.Seriablizable 和 java.lang.Comparable 两个接口;
- 所有的枚举值都是 public static final 的,且非抽象的枚举类不能再派生子类;
- 枚举类的所有实例(枚举值)必须在枚举类的第一行显式地列出,否则这个枚举类将永远不能产生实例。列出这些实例(枚举值)时,系统会自动添加 public static final 修饰,无需程序员显式添加。
三:Enum 使用
1 package com.ljq.test; 2 3 /** 4 * 枚举用法详解 5 * 6 * @author jiqinlin 7 * 8 */ 9 public class TestEnum { 10 /** 11 * 普通枚举 12 * 13 * @author jiqinlin 14 * 15 */ 16 public enum ColorEnum { 17 red, green, yellow, blue; 18 } 19 20 /** 21 * 枚举像普通的类一样可以添加属性和方法,可以为它添加静态和非静态的属性或方法 22 * 23 * @author jiqinlin 24 * 25 */ 26 public enum SeasonEnum { 27 //注:枚举写在最前面,否则编译出错 28 spring, summer, autumn, winter; 29 30 private final static String position = "test"; 31 32 public static SeasonEnum getSeason() { 33 if ("test".equals(position)) 34 return spring; 35 else 36 return winter; 37 } 38 } 39 40 /** 41 * 性别 42 * 43 * 实现带有构造器的枚举 44 * 45 * @author jiqinlin 46 * 47 */ 48 public enum Gender{ 49 //通过括号赋值,而且必须带有一个参构造器和一个属性跟方法,否则编译出错 50 //赋值必须都赋值或都不赋值,不能一部分赋值一部分不赋值;如果不赋值则不能写构造器,赋值编译也出错 51 MAN("MAN"), WOMEN("WOMEN"); 52 53 private final String value; 54 55 //构造器默认也只能是private, 从而保证构造函数只能在内部使用 56 Gender(String value) { 57 this.value = value; 58 } 59 60 public String getValue() { 61 return value; 62 } 63 } 64 65 /** 66 * 订单状态 67 * 68 * 实现带有抽象方法的枚举 69 * 70 * @author jiqinlin 71 * 72 */ 73 public enum OrderState { 74 /** 已取消 */ 75 CANCEL {public String getName(){return "已取消";}}, 76 /** 待审核 */ 77 WAITCONFIRM {public String getName(){return "待审核";}}, 78 /** 等待付款 */ 79 WAITPAYMENT {public String getName(){return "等待付款";}}, 80 /** 正在配货 */ 81 ADMEASUREPRODUCT {public String getName(){return "正在配货";}}, 82 /** 等待发货 */ 83 WAITDELIVER {public String getName(){return "等待发货";}}, 84 /** 已发货 */ 85 DELIVERED {public String getName(){return "已发货";}}, 86 /** 已收货 */ 87 RECEIVED {public String getName(){return "已收货";}}; 88 89 public abstract String getName(); 90 } 91 92 public static void main(String[] args) { 93 //枚举是一种类型,用于定义变量,以限制变量的赋值;赋值时通过“枚举名.值”取得枚举中的值 94 ColorEnum colorEnum = ColorEnum.blue; 95 switch (colorEnum) { 96 case red: 97 System.out.println("color is red"); 98 break; 99 case green: 100 System.out.println("color is green"); 101 break; 102 case yellow: 103 System.out.println("color is yellow"); 104 break; 105 case blue: 106 System.out.println("color is blue"); 107 break; 108 } 109 110 //遍历枚举 111 System.out.println("遍历ColorEnum枚举中的值"); 112 for(ColorEnum color : ColorEnum.values()){ 113 System.out.println(color); 114 } 115 116 //获取枚举的个数 117 System.out.println("ColorEnum枚举中的值有"+ColorEnum.values().length+"个"); 118 119 //获取枚举的索引位置,默认从0开始 120 System.out.println(ColorEnum.red.ordinal());//0 121 System.out.println(ColorEnum.green.ordinal());//1 122 System.out.println(ColorEnum.yellow.ordinal());//2 123 System.out.println(ColorEnum.blue.ordinal());//3 124 125 //枚举默认实现了java.lang.Comparable接口 126 System.out.println(ColorEnum.red.compareTo(ColorEnum.green));//-1 127 128 //-------------------------- 129 System.out.println("==========="); 130 System.err.println("季节为" + SeasonEnum.getSeason()); 131 132 133 //-------------- 134 System.out.println("==========="); 135 for(Gender gender : Gender.values()){ 136 System.out.println(gender.value); 137 } 138 139 //-------------- 140 System.out.println("==========="); 141 for(OrderState order : OrderState.values()){ 142 System.out.println(order.getName()); 143 } 144 } 145 146 }
四:枚举集合的使用
java.util.EnumSet和java.util.EnumMap是两个枚举集合。EnumSet保证集合中的元素不重复;EnumMap中的 key是enum类型,而value则可以是任意类型
JDK5.0 中在增加 Enum 类的同时,也增加了两个工具类 EnumSet 和 EnumMap,这两个类都放在 java.util 包中。EnumSet 是一个针对枚举类型的高性能的 Set 接口实现。EnumSet 中装入的所有枚举对象都必须是同一种类型,在其内部,是通过 bit-vector 来实现,也就是通过一个 long 型数。EnumSet 支持在枚举类型的所有值的某个范围中进行迭代。
1
|
enum WeekDayEnum { Mon, Tue, Wed, Thu, Fri, Sat, Sun } |
你能够在每周七天日期中进行迭代,EnumSet 类提供一个静态方法 range 让迭代很容易完成:
1
2
3
|
for(WeekDayEnum day : EnumSet.range(WeekDayEnum.Mon, WeekDayEnum.Fri)) { System.out.println(day); } |
打印结果如下:
1
2
3
4
5
|
Mon Tue Wed Thu Fri |
EnumSet 还提供了很多个类型安全的获取子集的 of 方法,很容易取得子集:
1
2
3
4
|
EnumSet< WeekDayEnum > subset = EnumSet.of(WeekDayEnum.Mon, WeekDayEnum.Wed); for (WeekDayEnum day : subset) { System.out.println(day); } |
打印结果如下:
1
2
|
Mon Wed |
与 EnumSet 类似,EnumMap 也是一个高性能的 Map 接口实现,用来管理使用枚举类型作为 keys 的映射表,内部是通过数组方式来实现。EnumMap 将丰富的和安全的 Map 接口与数组快速访问结合到一起,如果你希望要将一个枚举类型映射到一个值,你应该使用 EnumMap。看下面的例子:
1
2
3
4
5
6
7
8
9
10
11
12
|
// 定义一个 EnumMap 对象,映射表主键是日期枚举类型,值是颜色枚举类型 private static Map< WeekDayEnum , RainbowColor> schema = new EnumMap< WeekDayEnum , RainbowColor>(WeekDayEnum.class); static{ // 将一周的每一天与彩虹的某一种色彩映射起来 for (int i = 0; i < WeekDayEnum.values().length; i++) { schema.put(WeekDayEnum.values()[i], RainbowColor.values()[i]); } } System.out.println("What is the lucky color today?"); System.out.println("It's " + schema.get(WeekDayEnum.Sat)); |