Java枚举

枚举enum

1、枚举类型:Java SE5引入了枚举类型,使用enum关键字,用于处理程序中稳定的数据集;
2、枚举的创建:枚举量为常量,所以命名时要使用大写命名;
public enum Color {     
     RED,YELLOW,GREEN,BLUE;
}
3、使用枚举
Color red = Color.RED;
System.out.println(red.toString());          //Output: RED
intcompareTo(E o)
          比较此枚举与指定对象的顺序。
 booleanequals(Object other)
          当指定对象等于此枚举常量时,返回 true。
protected  voidfinalize()
          枚举类不能有 finalize 方法。
 Stringname()
          返回此枚举常量的名称,在其枚举声明中对其进行声明。
 intordinal()
          返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。
 StringtoString()
          返回枚举常量的名称,它包含在声明中。
static
<T extends Enum<T>>
T
valueOf(Class<T> enumType, String name)  

遍历枚举量:
for(Color color : Color.values( )){
     system.out.println(color+" "+ color.ordinal());
}
enum的枚举量本身就是常量,很适合在switch中使用,作为选项;:
public class test{
     Color color;
     public test(Color color){
          this.color = color;}
     public void descirble(){
          switch(color){
               case RED: System.out.println(...);break;
               case YELLOW: .......
               case GREEN:.........
          }
     }
}





静态导入和在枚举中的使用

1、静态导入import static,将某个类中的常量导入,在该类中可以直接使用该常量;
class Student{
     static String name = "assad";
     static int id = "233333";
     .......
} 
import static Student.name;
import static Student.id;          // import Student.*;
calss Test{
     main(){ println(name+id)};          //在没有静态导入时:println(Student.name+Student.id);
}


2、枚举的静态导入
enum Color{     RED,YELLOW,GREEN     }
import static Color.*;
class Test{
     main(){     Color red = RED;     }          //没有静态导入时:Color red = Color.RED;
}






使用接口组织枚举

1、所有的enum都继承自 java.lang.Enum类,由于Java不允许多重继承, 因此enum不可再继承其他的类,而应该用继承的方式实现多态;
2、除了不能继承,基本可以把enum看成一个类, 因此也可以向enum添加方法,甚至main方法;
public enum Color{
     RED("The light is red"),
     YELLOW("The light is yellow"),
     GREEN("The light is green");          //此处的RED、YELLOW、GREEN为枚举量,相当于Color类的实例,只不过在Color中实例是固定的;
     private String description;
     public Color(String description;){     this.description = description;     }
     public String getString(){     return description;     }
     public void main(String[] args){
           for(Color c : Color.values())
               System.out.println( c + c.getString() );   
     }
}



3、使用接口对一个enum中的枚举元素进行分类:
      对于enum而言,实现接口是使其子类化的唯一办法
public interface Food{
     enum Appetizer implements Food {SALAD,SOUP,SPRING_ROLLS}
     enum MainCourse implements Food {HUMMOUS,LASAGNE,BURRITO}
     enum Dessert implements Food {FRUIT,TIRAMISU}
}
//相当于在Food接口中定义上实现该接口的内部类;
//Test
main(){
     Food food1= Appetizer.SALAD;
     Food food2 = MainCourse.HUMMOUS;
}
4、创建枚举的枚举,实现对枚举的分类
public enum Course{
     APPETIZER(Food.Apperizer.class);
     MAINCOURSE(Food.MainCourse.class);
     DESSERT(Food.Dessert.class);
     private Food[] values;
     private Course(Class<? extends Food> kind){ values = kind.getEnumConstant() };  
     //T [ ] Class<T>.getEnumConstants()  获取一个类的所有枚举量;
     public Food ranodmSelecion(){     return RandomEnums.random(values);     }
}
//Test
main(){
     for(Course cour : Course.values()){
          Food food  = cour.randomSelection();
          System.out.println(food);
     }
}//这样通过两层的enum,就可以打印出一套随机的Course组合;





使用enum实现对枚举量的随机选取

import java.util.Random;
public class RandomEnums{
     private static Random rand = new Random();
     public static <T extends Enum<T>> random(Class<T> enumClass){     
          return random(enumClass.getEnumConstants());
     }
     public static <T extends Enum<T>> random(T[ ] values){
          return values[rand.nextInt(values.length)];
     }
}
//Test:
main(){
     Color randomColor = RandomEnums.random(Color.class);
     Color randomColor2 =RandomEnums.random(Color.values());
}





使用EnumSet代替Enum


1、Java SE5引入了EnumSet,是为了通过enum创建一种替代品,替代传统基于int的“位标志”,EnumSet优点在于:
①EnumSet在说明一个二进制位是否存在时,具有更好地表达能力,而且无需当心性能;
②可以自EnumSet中添加和删除元素,但不能在Enum中删除和添加元素;
2、示例代码:
enum AlarmPoints{     A1,A2,A3,A4,B1,B2,B3     }
import static AlarmPoints.*;
main(){
     EnumSet<AlarmPoints> points = EnumSet.allof(AlarmPoints.class);        //创建包含AlarmPoints枚举量的EnumSet
     EnumSet<AlarmPoints> p2 = EnumSet.noneof(AlarmPoints.class);         //创建AlarmPoints类型的空EnumSet
     EnumSet<AlarmPoints> p3 = EnumSet.of(A1,A2,B1,B2);          //创建包含AlarmPoints中若干枚举量的EnumSet
     p2.add(AlarmPoints.A1);
     p2.add(p3)
     points.removeAll(p2);
     points.removeAll(EnumSet.of(A4));
}





使用EnumMap

1、EnumMap是一种特殊的Map, 它要求其所的键(key)必须来自于一个enum,由于enum本身的限制,使得EnumMap在内部可以有数组组成, 因此EnumMap的速度很快
2、EnumMap的创建,其他操作和一般的Map一样;
EnumMap<K,V> map = new EnumMap<K,V>(class<K> keytype);
EnumMap<K,V> map = new  EnumMap<K<V>(EnumMap<? extends K,V> m);     //使用一个EnumMap创建,同时具有m的所有映射;
示例:
EnumMap<Color,Inetegr> m1 = new EnumMap<Color,Integer>(Color.class);
EnumMap<Color,Integer> m2 = new EnumMap<Color,Integer>(m1);




常量相关方法

1、J ava的enum允许程序员为enum实例编写方法,从而为每个enum实例赋予各自不同的行为;
      要实现常量方法,要先为enum定义一个abstract方法,然后为每一个enum实现该抽象方法
public enum SpecificMethod{
     DATE{
          String geInfo(){     return DateFormat.getDateInstance().format(new Date());     }
     }
     CLASSPATH{
          String getInfo(){     return System.getenv("CLASSPATH");     }
     }
     VERSION{
          String getInfo(){     return System.getProperty("java.version");     }
     }
     abstract String getInfo();
}
//通过调用不同枚举实例的getInfo方法,体现出enum多态的行为;
//Test
main(){
     for(SpecificMethod method : SpecificMethod.values())
          System.out.println(method.getInfo());
}
※与直接使用匿名内部类相比,定义常量方法语法更加高效,简洁;



2、除了实现abstratc方法以外,也可以请将其作为普通方法实现 ,同时在枚举常量内部对其进行覆盖;
public enum Points{
     A1,A2,A5,
     A3{ 
         String description(){     return "VIP room" ;}
     }
     A4{
          String description(){     return "bathroom"; }
     }
     String description(){     return "room"};
}







19.8 多路分发

1、Java支持单路分发,如果要执行的操作包含了不止一个类型未知的对象时,Java的动态绑定机制只能处理其中的一个类型;
2、实现两路分发的思路:要有两个方法调用,第一个方法调用决定第一个未知类型,第二个方法调用决定第二个未知类型;
public enum OutCome {   WIN,LOSE,DRAW }
public interface Item {
       OutCome compete(Item it);
       OutCome eval(Paper p);
       OutCome eval(Scissors s);
       OutCome eval(Rock r);
}
public class Paper implements Item{
       public OutCome compete(Item it){       return it.eval(this);}
       public OutCome eval(Paper p){      return DRAW;}
       public OutCome eval(Scissors s){       return LOSE; }
       public OutCome eval(Rock r){       return WIN;}
       public String toString(){      return "Paper"; }
}
public class Scissors implements Item{
       public OutCome compete(Item it){       return it.eval(this); }
       public OutCome eval(Paper p){       return  WIN; }
       public OutCome eval(Scissors s){       return DRAW;}
       public OutCome eval(Rock r){       return LOSE; }
       public String toString(){       return "Scissors"; }
}
public class Rock implements Item{
       public OutCome compete(Item it){       return it.eval(this);}
       public OutCome eval(Paper p){       return LOSE; }
       public OutCome eval(Scissors s){       return WIN; }
       public OutCome eval(Rock r){       return DRAW; }
       public String toString(){        return "Rock"; }
}

public class RoShamBo {
       static final int SIZE = 20;
       private static Random rand = new Random();
  
       public static Item newItem(){
             switch(rand.nextInt(3)){
             default:
             case 0: return new Paper();
             case 1:      return new Scissors();
             case 2: return new Rock();
             }
       }
       public static void match(Item a,Item b){
             System.out.println(a+" VS "+b+" : "+a.compete(b));
       }  
       public static void main(String[] args){
             for(int i=0;i<SIZE;i++){
                    match(newItem(),newItem());
             }
       }
}









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值