Java 枚举7常见种用法
http://softbeta.iteye.com/blog/1185573
DK1.5引入了新的类型——枚举。在Java中它虽然算个“小”功能,却给我的开发带来了“大”方便。
用法一:常量
在JDK1.5之前,我们定义常量都是:public static fianl....。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。
- public enum Color {
- RED, GREEN, BLANK, YELLOW
- }
用法二:switch
JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。
- 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;
- }
- }
用法四:覆盖枚举的方法
下面给出一个toString()方法覆盖的例子。
- 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);
- }
- }
用法六:使用接口组织枚举
- 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则可以是任意类型。关于这个两个集合的使用就不在这里赘述,可以参考JDK文档。
关于枚举的实现细节和原理请参考:
参考资料:《ThinkingInJava》第四版
java枚举类型
http://www.cnblogs.com/Fskjb/archive/2009/08/03/1537917.html
- public class TestEnum {
- /*最普通的枚举*/
- public enum ColorSelect {
- red, green, yellow, blue;
- }
- /* 枚举也可以象一般的类一样添加方法和属性,你可以为它添加静态和非静态的属性或方法,这一切都象你在一般的类中做的那样. */
- public enum Season {
- // 枚举列表必须写在最前面,否则编译出错
- winter, spring, summer, fall;
- private final static String location = "Phoenix";
- public static Season getBest() {
- if (location.equals("Phoenix"))
- return winter;
- else
- return summer;
- }
- }
- /*还可以有构造方法*/
- public enum Temp {
- /*通过括号赋值,而且必须有带参构造器和一属性跟方法,否则编译出错
- * 赋值必须是都赋值或都不赋值,不能一部分赋值一部分不赋值
- * 如果不赋值则不能写构造器,赋值编译也出错*/
- absoluteZero(-459), freezing(32),boiling(212), paperBurns(451);
- private final int value;
- public int getValue() {
- return value;
- }
- //构造器默认也只能是private, 从而保证构造函数只能在内部使用
- Temp(int value) {
- this.value = value;
- }
- }
- public static void main(String[] args) {
- /*
- * 枚举类型是一种类型,用于定义变量,以限制变量的赋值 赋值时通过"枚举名.值"来取得相关枚举中的值
- */
- ColorSelect m = ColorSelect.blue;
- switch (m) {
- /*注意:枚举重写了ToString(),说以枚举变量的值是不带前缀的
- *所以为blue而非ColorSelect.blue
- */
- 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("遍历ColorSelect中的值");
- /*通过values()获得枚举值的数组*/
- for (ColorSelect c : ColorSelect.values()) {
- System.out.println(c);
- }
- System.out.println("枚举ColorSelect中的值有:"+ColorSelect.values().length+"个");
- /*ordinal()返回枚举值在枚举中的索引位置,从0开始*/
- System.out.println(ColorSelect.red.ordinal());//0
- System.out.println(ColorSelect.green.ordinal());//1
- System.out.println(ColorSelect.yellow.ordinal());//2
- System.out.println(ColorSelect.blue.ordinal());//3
- /*枚举默认实现了java.lang.Comparable接口*/
- System.out.println(ColorSelect.red.compareTo(ColorSelect.green));
- System.out.println(Season.getBest());
- for(Temp t:Temp.values()){
- /*通过getValue()取得相关枚举的值*/
- System.out.println(t+"的值是"+t.getValue());
- }
- }
- }
一步步构造int型枚举
http://www.189works.com/article-18597-1.html
在Java 1.5之前,我们经常会把类型、状态、性别等取值范围很小而且比较固定的数据存储为int型常量,在枚举类型出现之前,大家都不会觉得有什么不便,然而在枚举类型出现之后,这种方式的缺点就明显了,一个是不可罗列,另一个是弱类型。然而int型仍然有int型的好处,比如持久化存储、位运算都要比枚举类型更加方便,所以如果有一种方式能够把两者综合一下就好了,下面我就介绍一种把两者结合起来的小技巧。
“int型枚举”是为了简化概念取的一个名字,并不是很准确,姑且这样一叫吧,觉得名字不好并且恰好手里有砖的可以拍了。
首先我们声明一个接口,以方便标识“int型枚举”这个抽象概念,接口里定义一个toInt()方法,用以将枚举对象转化成int值:
- public interface IntEnum {
- int toInt();
- }
现在我们用Sex类为例来实现这个IntEnum接口:
- public enum Sex implements IntEnum {
- MALE {
- @Override
- public int toInt()
- {
- return 1;
- }
- },
- FEMALE {
- @Override
- public int toInt()
- {
- return 2;
- }
- }
- }
OK,从代码里我们可以看出,MALE转化成int是1,FEMALE是2(当然有人说MALE为1,FEMALE为0更形象,我想说,你太猥琐了)。
下面要做的是实现是从int到Sex的逆向转化,有经验的同学已经想到了,对,没错,我们只需要构造一个int到Sex的Map映射问题就解决了,为了让代码尽可能的复用,我们把这个方法写在一个工具类里,JDK针对特定类型的工具类都喜欢以[针对的类型s]的方式命名,所以我们也随大流,就叫IntEnums(如果你不知道泛型相关的知识,请自行翻书):
- public class IntEnums {
- public static <T extends Enum<T> & IntEnum> Map<Integer, T> map(Class<T> clazz)
- {
- Map<Integer, T> instanceMap = new HashMap<Integer, T>();
- EnumSet<T> values = EnumSet.allOf(clazz);
- for(T value : values)
- {
- instanceMap.put(value.toInt(), value);
- }
- return instanceMap;
- }
- }
现在工具类建好了,该考虑转化操作怎么搞才方便用的问题了,我们知道Enum都有一个valueOf方法,用于把字符串直接转化成Enum对象,我们可以借用这个方法名,重载它,实现IntEnum从int到枚举的转化,所以Sex的最终代码如下:
- public enum Sex implements IntEnum {
- MALE {
- @Override
- public int toInt()
- {
- return 1;
- }
- },
- FEMALE {
- @Override
- public int toInt()
- {
- return 2;
- }
- };
- private static Map<Integer, Sex> instanceMap = IntEnums.map(Sex.class);
- public static Sex valueOf(int i)
- {
- return instanceMap.get(i);
- }
- }