《Java编程思想》学习笔记16——枚举

1.在枚举中添加方法:

Java中的枚举是一种特殊的类,不但可以添加字段,构造方法,普通方法,甚至可以添加main()方法,例子如下:

[java] view plaincopy
  1. public enum Test{  
  2.     //调用枚举构造方法创建枚举对象  
  3.     WEST(“Go west”), NORTH(“Go north”),  
  4.     EAST(“Go east”), SOUTH(“Go south”);  
  5. private String description;  
  6.     //私有构造方法  
  7. private Test(String description){  
  8.         this.description = description;  
  9. }  
  10. public String getDescription(){  
  11.     return description;  
  12. }  
  13. public static void main(String[] args){  
  14.     for(Test witch : Test.values()){  
  15.     System.out.println(witch + “: ” + witch.getDescription());  
  16. }  
  17. }  
  18. }  

输出结果:

WEST:Go west

NORTH:Go north

EAST:Go east

SOUTH:Go south

注意:若要在枚举中定义字段和方法,必须在枚举对象的分号之后,java强制规定枚举对象必须放在枚举的最开始处。

另外,枚举的构造方法必须是private的,因为只允许在枚举内部定义枚举对象时使用,不允许在枚举类之后使用枚举的构造方法。

2.switch分支语句中使用枚举:

Java的switch分支语句中,switch的条件只能是整数数值类型,在JDK5以后枚举之后,由于枚举对象的顺序也是整数数值,因此switch也支持枚举,例子如下:

[java] view plaincopy
  1. enum Signal{GREEN, YELLOW, RED}  
  2. public class TrafficLight{  
  3.     Signal color = Signal.RED;  
  4.     public void change(){  
  5.         switch(color){  
  6.     case RED:  
  7.         color = Signal.GREEN;  
  8.         break;  
  9.     case GREEN:  
  10.         color = Signal.YELLOW;  
  11.         break;  
  12.     case YELLOW:  
  13.         color = Signal.RED;  
  14.         break;  
  15. }  
  16. }  
  17. public String toString(){  
  18.     return “The traffic light is ” + color;  
  19. }  
  20. public static void main(String[] args){  
  21.     TrafficLight t = new TrafficLight();  
  22.     for(int i=0; i<5; i++){  
  23.         System.out.println(t);  
  24.         t.change();  
  25. }  
  26. }  
  27. }  

输出结果:

The traffic light is RED

The traffic light is GREEN

The traffic light is YELLOW

The traffic light is RED

The traffic light is GREEN

3.枚举Set:

EnumSet枚举Set是JDK5中引入的与枚举类型一起使用的专用Set实现,EnumSet中所有键都必须来自单个枚举类型,枚举Set在内部表示为位向量。位向量表示形式的EnumSet非常紧凑高效,空间性和时间性非常好,同时由于枚举对象含义清楚,因此EnumSet可以替换传统技艺int的位标志(在程序开发中,很多时候需要使用一串数字序列的位标志,每位代表不同的含义,例如网络协议等)。例子如下:

[java] view plaincopy
  1. //星期枚举  
  2. public enum Week{  
  3.     MON, TUE, WEN, THU, FRI, SAT, SUN  
  4. }  
  5.   
  6. import java.util.*;  
  7. //EnumSet例子  
  8. public class EnumSets{  
  9.     public static void main(String[] args){  
  10.         //EnumSet的noneOf方法创建指定枚举类型的空EnumSet  
  11.         EnumSet<Week> weeks = EnumSet.noneOf(Week.class);  
  12.         weeks.add(MON);  
  13.         System.out.println(weeks);  
  14.         //EnumSet的of方法创建包含指定枚举类型元素的EnumSet  
  15.         weeks.addAll(EnumSet.of(TUE, WEN, THU));  
  16.         System.out.println(weeks);  
  17.         // EnumSet的allOf方法创建包含指定枚举类型所有元素的EnumSet  
  18.         weeks = EnumSet.allOf(Week.class);  
  19.         System.out.println(weeks);  
  20.         weeks.removeAll(EnumSet.of(FRI, SAT, SUN));  
  21. System.out.println(weeks);  
  22. // EnumSet的rang方法创建包含指定枚举类型两个元素之间的EnumSet  
  23. weeks.removeAll(EnumSet.rang(MON, WEN));  
  24. System.out.println(weeks);  
  25. // EnumSet的complementOf方法创建指定EnumSet所不包含元素的EnumSet  
  26. weeks.removeAll(EnumSet.complementOf(weeks));  
  27. System.out.println(weeks);  
  28. }  
  29. }  

输出结果:

[MON]

[MON, TUE, WEN, THU]

[MON, TUE, WEN, THU, FRI, SAT, SUN]

[MON, TUE, WEN, THU]

[THU]

[MON, TUE, WEN, FRI, SAT, SUN]

注意:EnumSet的元素排列是依据Enum的定义顺序排列的,所有的基本操作都在固定时间内执行,速度比HashSet可能更快。

4.枚举Map:

EnumMap是与枚举类型一起使用的专用Map实现,枚举Map中所有的键都必须来自单个枚举类型,枚举Map在内部表示为数组。和EnumSet类似,EnumMap键的顺序也是和Enum的定义顺序一致,EnumMap的所有操作也都在固定时间内执行,它的速度可能比HashMap更快。

下面的例子使用EnumMap演示command interface的设计模式:
[java] view plaincopy
  1. public enum Directions{  
  2.     EAST, NORTH, WEST, SOUTH  
  3. }   
  4. interface Command{  
  5.     public void action();  
  6. }  
  7. public class EnumMaps{  
  8.     Public static void main(String[] args){  
  9.         EnumMap<Directions, Command> em =   
  10. new EnumMap<Directions, Command>(Directions.class);  
  11.         em.put(EAST, new Command(){  
  12.     public void action(){  
  13.     System.out.println(“Go east”);  
  14. }     
  15. });  
  16.         em.put(NORTH, new Command(){  
  17.     public void action(){  
  18.     System.out.println(“Go north”);  
  19. }     
  20. });  
  21.         em.put(WEST, new Command(){  
  22.     public void action(){  
  23.     System.out.println(“Go west”);  
  24. }     
  25. });  
  26.         for(Map.Entry<Directions, Command> e : em.entrySet()){  
  27.             System.out.println(e.getKey() + “: ” + e.getValue().action());  
  28. }  
  29. try{  
  30.     em.get(SOUTH).action();  
  31. }catch(Exception e){  
  32.     System.out.println(e);  
  33. }  
  34. }  
  35. }  

输出结果:

EAST: Go east

NORTH: Go north

WEST: Go west

java.lang.NullPointerException

从最后的空指针我们可以看出,EnumMap在创建时将Enum所有元素全部放进了key中,但是如果没有使用put显式将key和value关联的话,对应的value是null。

5.枚举特定方法:

在枚举中可以定义一个抽象的公共方法,然后各个枚举实例提供具体实现,实现一种类似匿名内部类的多态方式,例子如下:

[java] view plaincopy
  1. import java.util.*;  
  2. import java.text.*;  
  3.   
  4. public enum ConstantSpecificMethod{  
  5.     DATE_TIME{  
  6.     String getInfo(){  
  7.         return DateFormat.getDateInstance().format(new Date());  
  8. }  
  9. },  
  10. CLASS_PATH{  
  11.     String getInfo(){  
  12.         return System.getenv(“CLASSPATH”);  
  13. }  
  14. },  
  15. VERSION{  
  16.     String getInfo(){  
  17.         return System.getProperty(“java.version”);  
  18. }  
  19. };  
  20. //抽象方法  
  21. abstract String getInfo();  
  22. public static void main(String[] args){  
  23.     for(ConstantSpecificMethod csm : values()){  
  24.         System.out.println(csm.getInfo());  
  25. }  
  26. }  
  27. }  

通过这种多态方式,同样方便高效实现Commandinterface设计模式。

你可能感兴趣的:(《Java编程思想》学习笔记16——枚举)