枚举

定义

关键字enum可以将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序组件使用。

入门

//定义一个普通枚举
enum Shrubbery {GROUND, CRAWLING, HANGING}

public class EnumClass {
    public static void main(String[] args) {
        for (Shrubbery s : Shrubbery.values()) {
            //输出枚举的名称和索引下标
            System.out.println(s + " ordinal: " + s.ordinal());
            //重写了compareTo方法,输入当前枚举下标与指定枚举下标的差值
            System.out.println(s.compareTo(Shrubbery.CRAWLING));
            //equals方法与==符号作用相等
            System.out.println(s.equals(Shrubbery.CRAWLING));
            System.out.println(s == Shrubbery.CRAWLING);
            //所属的类
            System.out.println(s.getDeclaringClass());
            //输出实例声明的名字
            System.out.println(s.name());
            System.out.println("-------------");
        }

        //通过String数组,获取枚举实例,前提是该String必须在枚举中,否则报错
        for (String s : "HANGING CRAWLING GROUND".split(" ")) {
            Shrubbery shrubbery = Enum.valueOf(Shrubbery.class, s);
            System.out.println(shrubbery + "ordinal: " + shrubbery.ordinal());
        }
    }
}

构造函数创建枚举

需要注意的一个地方:在枚举中定义方法和属性,必须在枚举实例声明后才能定义。否则编译器报错。

public enum OzWitch {
    //通过私有构造函数,构建枚举
    WEST("this is WEST"),
    NORTH("this is NORTH"),
    EAST("this is EAST"),
    SOUTH("this is SOUTH");
    
    //重点:只能在枚举实例之后定义方法和属性
    private String description;
    //私有构造函数
    private OzWitch(String description){
        this.description = description;
    }

    public String getDescription() {
        return description;
    }

    public static void main(String[] args) {
        for (OzWitch o : OzWitch.values()){
            //循环遍历,并获取description字段信息
            System.out.println(o+":"+o.getDescription());
        }
    }
}

switch中使用

枚举具备整数值的次序,且可通过ordinal()方法取得次序,所以可以在switch中使用枚举

//定义枚举
enum Signal{GREEN,YELLOW,RED}

public class SwitchEnum {
    //默认的枚举值
    Signal color = Signal.RED;

    public void change(){
        //通过枚举就可以直接在枚举中使用,而不用调用ordinal()方法
        //显然编译器已经做了优化
        switch (color){
            case RED:color = Signal.GREEN;break;
            case GREEN:color = Signal.YELLOW;break;
            case YELLOW:color = Signal.RED;break;
        }
    }

    @Override
    public String toString() {
        return "SwitchEnum{" +
                "color=" + color +
                '}';
    }

    public static void main(String[] args) {
        SwitchEnum s = new SwitchEnum();
        for (int i = 0; i < 7; i++) {
            System.out.println(s);
            s.change();
        }
    }
}

随机读取

enum Activity{A,B,C,D,E,F,G}
public class EnumRandom{
    //定义随机对象
    private static Random random = new Random(47);
    // <T extends Enum<T>> 代表枚举对象
    public static <T extends Enum<T>> T random(Class<T> ec){
        return random(ec.getEnumConstants());
    }
    //重载random方法,目的是为了不破坏Enum的操作
    public static <T> T random(T[] values){
        return values[random.nextInt(values.length)];
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            //直接传入枚举类,就可以实现随机读取了
            System.out.println(random(Activity.class));
        }
    }
}

设计模式

单例模式

public class Singleton {
    //使用枚举,构建单例模式
    private Singleton() {
    }


    private enum SingletonEnum {
        //申明唯一一个单利枚举
        singletonEnum;
        //申请单利对象
        private Singleton singleton;

        SingletonEnum(){
            //在枚举的构造函数中,获取对象实例
            singleton = new Singleton();
        }

        //返回单例对象
        public Singleton getInstance(){
            return singleton;
        }
    }


    public static Singleton getInstance(){
        //直接返回枚举的getInstance方法,即可获取单例对象
        return SingletonEnum.singletonEnum.getInstance();
    }
}

策略模式

public class Strategy {
    public enum ROLE{
        //在枚举中实现抽象函数
        ADMIN{
            @Override
            public void speak(){
                System.out.println("我是管理员");
            }
        },
        USER{
            @Override
            public void speak(){
                System.out.println("我是用户");
            }
        },
        VIP{
            @Override
            public void speak(){
                System.out.println("我是vip");
            }
        };

        //声明一个抽象方法,目的是为了使角色有一个统一的行为
        public abstract void speak();
    }


    public static void main(String[] args) {
        //直接使用即可
        ROLE.ADMIN.speak();
        ROLE.USER.speak();
        ROLE.VIP.speak();
    }
}

总结

枚举在实际开发中运用的场景不多。在我所参与的项目中,枚举其实是作为业务表中的状态字段映射,通过使用枚举,不再使用硬编码。比如,状态字段state,有三种状态 0:未完成;2:完成中;2:已完成,判断状态时,不再用0/1/2去判断,而使用枚举定义的key和value去判断。这样在代码的可读行和维护性上,提高了很多。

public enum DemoEum {
    END(0, "未完成"),
    DOING(1,"完成中")
    FINISH(2,"已完成")
    ;
    private Integer key;
    private String value;

    public Integer getKey() {
        return key;
    }

    public void setKey(Integer key) {
        this.key = key;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    DemoEum (Integer key, String value) {
        this.key = key;
        this.value = value;
    }

未使用枚举时

    ....
    if(state == 0){//未完成。。。。
    }else if(state == 1){//完成中。。。。
    }
    ....

使用枚举

 ....
    if(state == DemoEum.END.getKey()){//未完成。。。。
    }else if(state == DemoEum.DOING.getKey()){//完成中。。。。
    }
    ....
posted @ 2020-10-21 11:13  dxyoung  阅读(85)  评论(0)    收藏  举报