Java 枚举

1. 概念

  enum的全称为 enumeration, 是 JDK 1.5 中引入的新特性。枚举可以集中统一地管理项目中的常量,通常用来表示错误码,状态机等。我们有时候会用 public static final来定义某种状态,枚举与之不同的是可以将各种状态值进行分类,只有同一类型的值才能比较,进而规范了这些状态值的使用。枚举值默认为从0开始的有序数值

  · 创建enum时,编译器会为你生成一个相关的类,这个类继承自java.lang.Enum(定义如下)

public abstract class Enum<E extends Enum<E>>
        implements Comparable<E>, Serializable {
    private final String name;
    private final int ordinal;
    protected Enum(String name, int ordinal) {
        this.name = name;
        this.ordinal = ordinal;
    }
    ...
}

  · 枚举类型的每一个值都将映射到 protected Enum(String name, int ordinal) 构造函数中

public enum Color{WHITE, BLACK;}; //这段代码实际上调用了2次 Enum(String name, int ordinal):
new Enum<WeekDay>("WHITE",0); 
new Enum<WeekDay>("BLACK",1);

 

2.遍历、switch 等常用操作

public class Test {

    public enum Operation {PLUS, MINUS, TIMES, DIVIDE}
    
    public static void main(String[] args) {
        
        for(Operation op : Operation.values()) {
            System.out.print(op.toString() + " ");
        }
        System.out.println();
        
        Operation op = Operation.MINUS;
        switch(op){
        case PLUS: 
            System.out.println("This is " + Operation.PLUS); break;
        case MINUS: 
            System.out.println("This is " + Operation.MINUS); break;
        case TIMES: 
            System.out.println("This is " + Operation.TIMES); break;
        default: 
            System.out.println("This is " + Operation.DIVIDE); break;
        }
    }
}

运行结果

PLUS MINUS TIMES DIVIDE
This is MINUS

 

3. enum自定义属性和方法

  Java允许在枚举中添加任意的方法和域,并实现任意的接口。

public class Test {

    public enum Operation {
        // 通过括号赋值,需有对应的构造函数.赋值必须都赋值或都不赋值!
        // 给每个枚举常量提供不同的数据操作行为
        PLUS("+",  1) { double apply(double x, double y){return x + y;} }, 
        MINUS("-", 2) { double apply(double x, double y){return x - y;} }, 
        TIMES("*", 3) { double apply(double x, double y){return x * y;} }, 
        DIVIDE("/",4) { double apply(double x, double y){return x / y;} };
        
        private final String symbol; 
        private int index;  // 自定义枚举值的位置,防止新增枚举值后顺序打乱
        Operation(String symbol, int index){
            this.symbol = symbol;
            this.index = index;
        }
        public int getIndex() {
            return index;
        }
        public String toString() {
            return symbol;
        }
        abstract double apply(double x, double y); // 自定义方法,定义为抽象方法后,每个枚举值都要实现该方法
    }
    
    public static void main(String[] args) {
        double x = 6.0;
        double y = 2.0;
        for (Operation op : Operation.values())
            System.out.printf("(%d) %.0f %s %.0f = %.0f%n", op.getIndex(), x, op, y, op.apply(x,y)); } }

运行结果

(1) 6 + 2 = 8
(2) 6 - 2 = 4
(3) 6 * 2 = 12
(4) 6 / 2 = 3

  enum可以实现接口,但不能继承其他类(它已经默认继承Enum类了)

interface Operation {
    double apply(double x,double y);
}
enum BasicOperation implements Operation {
    PLUS("+")  { public double apply(double x,double y) { return x + y; } },
    MINUS("-") { public double apply(double x,double y) { return x - y; }},
    TIMES("*") { public double apply(double x,double y) { return x * y; }},
    DIVIDE("/") {public double apply(double x,double y) { return x / y; }};
    private final String symbol;
    BasicOperation(String symbol) {
        this.symbol = symbol;
    }
    @Override 
    public String toString() {
        return symbol;
    }
}
enum ExtendedOperation implements Operation {
    EXP("^") {public double apply(double x,double y) { return Math.pow(x,y);}},
    REMAINDER("%") {public double apply(double x,double y) {return x % y;}};
    private final String symbol;
    ExtendedOperation(String symbol) {
        this.symbol = symbol;
    }
    @Override 
    public String toString() {
        return symbol;
    }
}

public class Test {
    public static void main(String[] args) {
        double x = 6;
        double y = 2;
        test(ExtendedOperation.class,x,y);
    }
    private static <T extends Enum<T> & Operation> void test(
        Class<T> opSet,double x, double y) {
        for (Operation op : opSet.getEnumConstants()) {
            System.out.printf("%.0f %s %.0f = %.0f%n", x, op, y, op.apply(x,y));
        }
    }
}

运行结果

6 ^ 2 = 36
6 % 2 = 0

 

4. EnumSet和EnumMap

  Java中提供了两个方便操作enum的工具类——EnumSet和EnumMap。
  EnumSet 是枚举类型的高性能Set实现。它要求放入它的枚举常量必须属于同一枚举类型。
  EnumMap是专门为枚举类型量身定做的Map实现。虽然使用其它的Map实现(如HashMap)也能完成枚举类型实例到值得映射,但是使用EnumMap会更加高效:它只能接收同一枚举类型的实例作为键值,并且由于枚举类型实例的数量相对固定并且有限,所以EnumMap使用数组来存放与枚举类型对应的值。这使得EnumMap的效率非常高。

public class Test {

    public enum Operation {PLUS, MINUS, TIMES, DIVIDE}
    
    public static void main(String[] args) {
        System.out.println("EnumSet:");
        EnumSet<Operation> opSet = EnumSet.allOf(Operation.class);
        for(Operation op : opSet) {
            System.out.print(op.toString() + "  ");
        }
        System.out.println("\nEnumMap:");
        
        EnumMap<Operation, String> opMap = new EnumMap(Operation.class);
        opMap.put(Operation.PLUS, "+");
        opMap.put(Operation.MINUS, "-");
        Iterator<Map.Entry<Operation, String>> itr = opMap.entrySet().iterator();
        for(; itr.hasNext(); ) {
            Map.Entry<Operation, String> op = itr.next();
            System.out.print(op.getKey() + op.getValue() + "  ");
        }
    }
}

 

posted @ 2017-04-21 15:59  安小  阅读(189)  评论(0编辑  收藏  举报