zoukankan      html  css  js  c++  java
  • Java enum枚举在实际项目中的常用方法

    在项目实际开发过程中,经常会遇到对某些固定的值、字典项的定义的需求,很多项目经常使用常量来定义,其实在jdk1.5就已经引入了枚举,使用枚举可以更好的解决这类需求,本文主要记录枚举的优势以及经常在项目中使用的方法。

    知识点

    • 枚举类命名
      枚举类的命名通常需要Enum为后缀,枚举成员名称需要全大写,单词间用下划线隔开。
    • 枚举类不允许使用 extends 关键字
      枚举类默认会继承java.lang.Enum,由于java是单继承,所以在定义枚举类时不允许再继承其他类,但可以实现多个接口
    • 枚举的比较可以直接使用 ==
      枚举是不允许被new出来的,枚举类里的构造函数都限定为私有化,是不允许使用public定义构造函数的。枚举的赋值,如果是同一个元素,则会指向同一个地址,所以是可以直接使用==的,当然在Enum类中,重写了equals方法(如下图),所以也是可以用equals来判断。
      在这里插入图片描述
    • 枚举常用方法
    方法名 用途
    name() 返回枚举常量名
    toString() 返回枚举常量名
    values() 返回枚举成员数组
    valueOf() 通过枚举常量名返回枚举
    ordinal() 返回枚举常量在enum声明中的位置,位置是从0开始计数的
    • 枚举在switch中的使用
      枚举在switch中的使用,优势在于能控制case的范围(看以下实例),并且在idea中有相关提示
    • 枚举在单例模式的使用
      首先使用枚举类实现单例模式,写法相当简单,看最后的实例;其次枚举是线程安全、单一实例(由于构造方法都是私有的,不能被new)

    实例

    1. 最简单的枚举

    在项目中经常会遇到一些固定值的定义,以往都是用常量来定义,以下用实例说明,为啥枚举的方式优于常量的方式,以下就以季节的定义为例

    1.1 使用常量来实现

    /**
     * @Description: 季节常量定义
     */
    public class SeasonConst {
        /**
         * 春季
         */
        public static final String SPRING = "SPRING";
        /**
         * 夏季
         */
        public static final String SUMMER = "SUMMER";
        /**
         * 秋季
         */
        public static final String AUTUMN = "AUTUMN";
        /**
         * 冬季
         */
        public static final String WINTER = "WINTER";
    }
    

    以上实例虽然实现了功能,但有两点比较明显的缺点:

    1. 常量值容易写错(特别是复制黏贴,但是忘记改对应的值,导致系统出bug),idea不会给任何提示。
      比如,某人粗心,在复制黏贴代码时变成(将春季、夏季都定义成春季了):
    /**
     * 春季
     */
    public static final String SPRING = "SPRING";
    /**
     * 夏季
     */
    public static final String SUMMER = "SPRING";
    
    1. 如果我想知道一年总共多少个季节,咋整?用常量定义的类,有点捉襟见肘

    1.2 使用枚举来实现,可以实现常量的所有功能,并能轻松解决以上提出的常量的两个缺点

    • 定义枚举类SeasonEnum
    public enum SeasonEnum {
        /**
         * 春季
         */
        SPRING,
        /**
         * 夏季
         */
        SUMMER,
        /**
         * 秋季
         */
        AUTUMN,
        /**
         * 冬季
         */
        WINTER
    }
    

    在SeasonEnum枚举类中,如果定义两个 SPRING,编译器会直接报错,很好解决了常量的第一个缺点

    • 该枚举类的使用(1、获取枚举值的名称;2、枚举判断的使用;3、枚举循环的使用。通过枚举的循环,很好解决了常量的第二个缺点;)
    //获取枚举值的名称,与toString得到的结果一样
    String spring = SeasonEnum.SPRING.name();
    System.out.println(spring);
    
    //枚举判断的使用
    SeasonEnum springEnum1 = SeasonEnum.SPRING;
    SeasonEnum springEnum2 = SeasonEnum.SPRING;
    SeasonEnum summerEnum3 = SeasonEnum.SUMMER;
    //由于springEnum1、springEnum2都指向SPRING,所以输出true
    System.out.println("springEnum1 == springEnum2:" + (springEnum1 == springEnum2));
    //由于springEnum1指向SPRING、summerEnum3指向SUMMER,所以输出false
    System.out.println("springEnum1 == summerEnum3:" + (springEnum1 == summerEnum3));
    
    //循环枚举,打印枚举类中的所有枚举成员
    SeasonEnum[] seasonEnums = SeasonEnum.values();
    for (SeasonEnum seasonEnum : seasonEnums) {
        System.out.println(seasonEnum.name());
    }
    
    • 枚举在switch中的使用,如果case后跟不存在SeasonEnum类中的枚举(比如 case OTHER),则编译器会报错
    String enumName = "SPRING";
    SeasonEnum seasonEnum = SeasonEnum.valueOf(enumName);
    switch (seasonEnum){
        case SPRING:
           System.out.println(seasonEnum.name());
           break;
        case SUMMER:
            System.out.println(seasonEnum.name());
            break;
        case AUTUMN:
            System.out.println(seasonEnum.name());
            break;
        case WINTER:
            System.out.println(seasonEnum.name());
            break;
        default:
            System.out.println("other");
    }
    

    2.在枚举中使用自定义属性和方法

    项目中经常也会遇到一些字典项的定义,比如性别,包含存入数据库中的值,以及显示在页面上的值。以下通过实例来实现性别字典。

    • 定义SexEnum(注意看代码中的注解)
    public enum SexEnum {
        MAN("man","男"),
        WOMEN("women","女");
    
        private String sexCode;
    
        private String sexName;
    
        /**
         * 自定义构造函数,以完成枚举对sexCode、sexName赋值
         * @param sexCode
         * @param sexName
         */
        SexEnum(String sexCode,String sexName){
            this.sexCode = sexCode;
            this.sexName = sexName;
        }
    
        /**
         * 获取sexCode
         * @return
         */
        public String getSexCode() {
            return sexCode;
        }
    
        /**
         * 获取sexName
         * @return
         */
        public String getSexName() {
            return sexName;
        }
    
        /**
         * 项目中经常会根据code,转换成对应的name
         * 所以这里自定义方法,根据sexCode获取sexName
         * 通过循环enum来实现
         * @param sexCode
         * @return
         */
        public static String getSexNameByCode(String sexCode){
            String sexName = "sexCode不存在";
            SexEnum[] sexEnums = SexEnum.values();
            for (SexEnum sexEnum : sexEnums) {
                if(sexEnum.getSexCode().equals(sexCode)){
                    sexName =  sexEnum.getSexName();
                    break;
                }
            }
            return sexName;
        }
    
        /**
         * 项目中也有根据name,转换成对应的code
         * 所以这里自定义方法,根据sexName获取sexCode
         * 通过循环enum来实现
         * @param sexName
         * @return
         */
        public static String getSexCodeByName(String sexName){
            String sexCode = "sexName不存在";
            SexEnum[] sexEnums = SexEnum.values();
            for (SexEnum sexEnum : sexEnums) {
                if(sexEnum.getSexName().equals(sexName)){
                    sexCode =  sexEnum.getSexCode();
                    break;
                }
            }
            return sexCode;
        }
    
        /**
         * 根据sexCode获取SexEnum,在switch中使用
         * 通过循环enum来实现
         * @param sexCode
         * @return
         */
        public static SexEnum getEnumByCode(String sexCode){
            SexEnum[] sexEnums = SexEnum.values();
            for (SexEnum sexEnum : sexEnums) {
                if(sexEnum.getSexCode().equals(sexCode)){
                    return sexEnum;
                }
            }
            return null;
        }
    
        /**
         * 重写toString方法
         * @return
         */
        @Override
        public String toString() {
            return this.sexCode + ":" + this.sexName;
        }
    }
    
    • SexEnum枚举类的使用
    public class EnumMain {
    
        public static void main(String[] args){
            //循环带自定义方法的枚举
            SexEnum[] sexEnums = SexEnum.values();
            for (SexEnum sexEnum : sexEnums) {
                System.out.println("sexCode:"+sexEnum.getSexCode());
                System.out.println("sexName:"+sexEnum.getSexName());
                System.out.println("sexCode:sexName="+sexEnum.toString());
            }
    
            //根据sexCode获取sexName
            String sexName = SexEnum.getSexNameByCode("women");
            System.out.println("根据sexCode获取sexName:" + sexName);
    
            //根据sexName获取sexCode
            String sexCode = SexEnum.getSexCodeByName("男");
            System.out.println("根据sexName获取sexCode:" + sexCode);
    
            //通过传入的sexCode使用switch
            testSexEnumSwitch("women");
    
        }
        /**
         * 实际项目中,基本上都是传sexCode的,所以这里也根据传入的sexCode,使用switch方法
         * @param sexCode
         */
        private static void testSexEnumSwitch(String sexCode){
            //自定义getEnumByCode方法,通过sexCode获取SexEnum
            SexEnum sexEnum = SexEnum.getEnumByCode(sexCode);
            switch (sexEnum){
                case MAN:
                    System.out.println(sexEnum.toString());
                    break;
                case WOMEN:
                    System.out.println(sexEnum.toString());
                    break;
                default:
                    System.out.println("other");
            }
        }
    }
    

    3.通过枚举实现单例

    • 单例定义
    public enum Singleton {
        INSTALL;
        /**
         * 自定义方法
         */
        public void yourMethod(){
            System.out.println("do your business");
        }
    }
    
    • 调用方法
    Singleton.INSTALL.yourMethod();
    

    源码获取

    以上示例都可以通过我的GitHub获取完整的代码,点击获取

  • 相关阅读:
    ~随笔A007~html中input输入框的字数限制、同步input的输入内容至div中
    ~随笔A006~微信扫码的授权、用户绑定、关注公众号、消息反馈
    【CV】实验二:特征检测与匹配
    【笔记】DLX算法及常见应用
    【笔记】和算法无关的那些东东
    【笔记】康拓展开&逆康拓展开
    【笔记】离散对数
    【笔记】Shift-And算法&Shift-OR算法
    【模板】中缀表达式求值
    【笔记】数据库系统
  • 原文地址:https://www.cnblogs.com/mingsay/p/12390900.html
Copyright © 2011-2022 走看看