Java枚举用法


Java 枚举7常见种用法

http://softbeta.iteye.com/blog/1185573

DK1.5引入了新的类型——枚举。在Java中它虽然算个“小”功能,却给我的开发带来了“大”方便。

用法一:常量

在JDK1.5之前,我们定义常量都是:public static fianl....。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。

 

Java代码   收藏代码
  1. public enum Color {  
  2.   RED, GREEN, BLANK, YELLOW  
  3. }  
 

用法二:switch

JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。

 

Java代码   收藏代码
  1. enum Signal {  
  2.     GREEN, YELLOW, RED  
  3. }  
  4. public class TrafficLight {  
  5.     Signal color = Signal.RED;  
  6.     public void change() {  
  7.         switch (color) {  
  8.         case RED:  
  9.             color = Signal.GREEN;  
  10.             break;  
  11.         case YELLOW:  
  12.             color = Signal.RED;  
  13.             break;  
  14.         case GREEN:  
  15.             color = Signal.YELLOW;  
  16.             break;  
  17.         }  
  18.     }  
  19. }  
 

用法三:向枚举中添加新方法

如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。而且Java要求必须先定义enum实例。

 

Java代码   收藏代码
  1. public enum Color {  
  2.     RED("红色"1), GREEN("绿色"2), BLANK("白色"3), YELLO("黄色"4);  
  3.     // 成员变量  
  4.     private String name;  
  5.     private int index;  
  6.     // 构造方法  
  7.     private Color(String name, int index) {  
  8.         this.name = name;  
  9.         this.index = index;  
  10.     }  
  11.     // 普通方法  
  12.     public static String getName(int index) {  
  13.         for (Color c : Color.values()) {  
  14.             if (c.getIndex() == index) {  
  15.                 return c.name;  
  16.             }  
  17.         }  
  18.         return null;  
  19.     }  
  20.     // get set 方法  
  21.     public String getName() {  
  22.         return name;  
  23.     }  
  24.     public void setName(String name) {  
  25.         this.name = name;  
  26.     }  
  27.     public int getIndex() {  
  28.         return index;  
  29.     }  
  30.     public void setIndex(int index) {  
  31.         this.index = index;  
  32.     }  
  33. }  
 

用法四:覆盖枚举的方法

下面给出一个toString()方法覆盖的例子。

 

Java代码   收藏代码
  1. public enum Color {  
  2.     RED("红色"1), GREEN("绿色"2), BLANK("白色"3), YELLO("黄色"4);  
  3.     // 成员变量  
  4.     private String name;  
  5.     private int index;  
  6.     // 构造方法  
  7.     private Color(String name, int index) {  
  8.         this.name = name;  
  9.         this.index = index;  
  10.     }  
  11.     //覆盖方法  
  12.     @Override  
  13.     public String toString() {  
  14.         return this.index+"_"+this.name;  
  15.     }  
  16. }  
 

用法五:实现接口

所有的枚举都继承自java.lang.Enum类。由于Java不支持多继承,所以枚举对象不能再继承其他类。

 

Java代码   收藏代码
  1. public interface Behaviour {  
  2.     void print();  
  3.     String getInfo();  
  4. }  
  5. public enum Color implements Behaviour{  
  6.     RED("红色"1), GREEN("绿色"2), BLANK("白色"3), YELLO("黄色"4);  
  7.     // 成员变量  
  8.     private String name;  
  9.     private int index;  
  10.     // 构造方法  
  11.     private Color(String name, int index) {  
  12.         this.name = name;  
  13.         this.index = index;  
  14.     }  
  15. //接口方法  
  16.     @Override  
  17.     public String getInfo() {  
  18.         return this.name;  
  19.     }  
  20.     //接口方法  
  21.     @Override  
  22.     public void print() {  
  23.         System.out.println(this.index+":"+this.name);  
  24.     }  
  25. }  
 

用法六:使用接口组织枚举

 

Java代码   收藏代码
  1. public interface Food {  
  2.     enum Coffee implements Food{  
  3.         BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO  
  4.     }  
  5.     enum Dessert implements Food{  
  6.         FRUIT, CAKE, GELATO  
  7.     }  
  8. }  
 

用法七:关于枚举集合的使用

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

[java]  view plain copy
  1. public class TestEnum {  
  2.     /*最普通的枚举*/  
  3.     public enum ColorSelect {  
  4.         red, green, yellow, blue;      
  5.     }  
  6.   
  7.     /* 枚举也可以象一般的类一样添加方法和属性,你可以为它添加静态和非静态的属性或方法,这一切都象你在一般的类中做的那样. */  
  8.     public enum Season {  
  9.         // 枚举列表必须写在最前面,否则编译出错  
  10.         winter, spring, summer, fall;  
  11.   
  12.         private final static String location = "Phoenix";          
  13.   
  14.         public static Season getBest() {  
  15.             if (location.equals("Phoenix"))  
  16.                 return winter;  
  17.             else  
  18.                 return summer;  
  19.         }  
  20.     }  
  21.     /*还可以有构造方法*/  
  22.     public enum Temp {  
  23.         /*通过括号赋值,而且必须有带参构造器和一属性跟方法,否则编译出错 
  24.          * 赋值必须是都赋值或都不赋值,不能一部分赋值一部分不赋值 
  25.          * 如果不赋值则不能写构造器,赋值编译也出错*/  
  26.         absoluteZero(-459), freezing(32),boiling(212), paperBurns(451);  
  27.           
  28.         private final int value;  
  29.         public int getValue() {  
  30.             return value;  
  31.         }  
  32.         //构造器默认也只能是private, 从而保证构造函数只能在内部使用  
  33.         Temp(int value) {  
  34.             this.value = value;  
  35.         }  
  36.     }  
  37.   
  38.     public static void main(String[] args) {  
  39.         /* 
  40.          * 枚举类型是一种类型,用于定义变量,以限制变量的赋值 赋值时通过"枚举名.值"来取得相关枚举中的值 
  41.          */  
  42.         ColorSelect m = ColorSelect.blue;  
  43.         switch (m) {  
  44.         /*注意:枚举重写了ToString(),说以枚举变量的值是不带前缀的 
  45.           *所以为blue而非ColorSelect.blue 
  46.           */  
  47.    case red:  
  48.             System.out.println("color is red");  
  49.             break;  
  50.         case green:  
  51.             System.out.println("color is green");  
  52.             break;  
  53.         case yellow:  
  54.             System.out.println("color is yellow");  
  55.             break;  
  56.         case blue:  
  57.             System.out.println("color is blue");  
  58.             break;  
  59.         }  
  60.         System.out.println("遍历ColorSelect中的值");  
  61.         /*通过values()获得枚举值的数组*/  
  62.         for (ColorSelect c : ColorSelect.values()) {  
  63.             System.out.println(c);  
  64.         }     
  65.    System.out.println("枚举ColorSelect中的值有:"+ColorSelect.values().length+"个");  
  66.    /*ordinal()返回枚举值在枚举中的索引位置,从0开始*/  
  67.   System.out.println(ColorSelect.red.ordinal());//0  
  68.   System.out.println(ColorSelect.green.ordinal());//1  
  69.   System.out.println(ColorSelect.yellow.ordinal());//2  
  70.   System.out.println(ColorSelect.blue.ordinal());//3  
  71.   
  72.   /*枚举默认实现了java.lang.Comparable接口*/   
  73.   System.out.println(ColorSelect.red.compareTo(ColorSelect.green));  
  74.   
  75.   System.out.println(Season.getBest());  
  76.           
  77.         for(Temp t:Temp.values()){  
  78.             /*通过getValue()取得相关枚举的值*/  
  79.             System.out.println(t+"的值是"+t.getValue());  
  80.         }  
  81.   
  82.     }  
  83. }  

一步步构造int型枚举

http://www.189works.com/article-18597-1.html

在Java 1.5之前,我们经常会把类型、状态、性别等取值范围很小而且比较固定的数据存储为int型常量,在枚举类型出现之前,大家都不会觉得有什么不便,然而在枚举类型出现之后,这种方式的缺点就明显了,一个是不可罗列,另一个是弱类型。然而int型仍然有int型的好处,比如持久化存储、位运算都要比枚举类型更加方便,所以如果有一种方式能够把两者综合一下就好了,下面我就介绍一种把两者结合起来的小技巧。
“int型枚举”是为了简化概念取的一个名字,并不是很准确,姑且这样一叫吧,觉得名字不好并且恰好手里有砖的可以拍了。
首先我们声明一个接口,以方便标识“int型枚举”这个抽象概念,接口里定义一个toInt()方法,用以将枚举对象转化成int值:

[java]  view plain copy
  1. public interface IntEnum {  
  2.     int toInt();  
  3. }  

现在我们用Sex类为例来实现这个IntEnum接口:
[java]  view plain copy
  1. public enum Sex implements IntEnum {  
  2.     MALE {  
  3.         @Override  
  4.         public int toInt()  
  5.         {  
  6.             return 1;  
  7.         }  
  8.     },  
  9.     FEMALE {  
  10.         @Override  
  11.         public int toInt()  
  12.         {  
  13.             return 2;  
  14.         }  
  15.     }  
  16. }  

OK,从代码里我们可以看出,MALE转化成int是1,FEMALE是2(当然有人说MALE为1,FEMALE为0更形象,我想说,你太猥琐了)。
下面要做的是实现是从int到Sex的逆向转化,有经验的同学已经想到了,对,没错,我们只需要构造一个int到Sex的Map映射问题就解决了,为了让代码尽可能的复用,我们把这个方法写在一个工具类里,JDK针对特定类型的工具类都喜欢以[针对的类型s]的方式命名,所以我们也随大流,就叫IntEnums(如果你不知道泛型相关的知识,请自行翻书):
[java]  view plain copy
  1. public class IntEnums {  
  2.     public static <T extends Enum<T> & IntEnum> Map<Integer, T> map(Class<T> clazz)  
  3.     {  
  4.         Map<Integer, T> instanceMap = new HashMap<Integer, T>();  
  5.         EnumSet<T> values = EnumSet.allOf(clazz);  
  6.         for(T value : values)  
  7.         {  
  8.             instanceMap.put(value.toInt(), value);  
  9.         }  
  10.         return instanceMap;  
  11.     }  
  12. }  

现在工具类建好了,该考虑转化操作怎么搞才方便用的问题了,我们知道Enum都有一个valueOf方法,用于把字符串直接转化成Enum对象,我们可以借用这个方法名,重载它,实现IntEnum从int到枚举的转化,所以Sex的最终代码如下:
[java]  view plain copy
  1. public enum Sex implements IntEnum {  
  2.     MALE {  
  3.         @Override  
  4.         public int toInt()  
  5.         {  
  6.             return 1;  
  7.         }  
  8.     },  
  9.     FEMALE {  
  10.         @Override  
  11.         public int toInt()  
  12.         {  
  13.             return 2;  
  14.         }  
  15.     };  
  16.     private static Map<Integer, Sex> instanceMap = IntEnums.map(Sex.class);  
  17.     public static Sex valueOf(int i)  
  18.     {  
  19.         return instanceMap.get(i);  
  20.     }  
  21. }  
当然,有的同学可能想到,把转化过程完全封装在IntEnums里不是更好,这种想法是好的,然而一并考虑到并发安全、效率等问题,可能变得有些复杂,当然如果大家有更好的做法,请尽情发挥。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值