Java枚举

简介

枚举类型是一种使用一组预定义的常量表示的一种特殊数据类型。enum关键字在 java5 中引入,所有的枚举类默认都集成自java.lang.Enum类。

//基本写法
public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY 
}

枚举与常量比较

  • 优点
    1. 可读性更高
    2. 编译时检查减少代码错误(相对于基本数据类型的常量)
    3. 表现力更强(相对于基本数据类型的常量)
    4. 使用 == 对枚举进行比较提供编译时和运行时的安全性
  • 缺点
    1. 增加类的数目
    2. 数据转换麻烦
public class Date {

    private Day day;

    public static void main(String[] args) {
        Date today = new Date();
        //可能会出NPE
        if (today.getDay().equals(Day.FRIDAY)) {
            //todo
        }
        //使用==保证运行时安全
        if (today.getDay() == Day.FRIDAY) {
            //todo
        }
       //比较会得到true
        if (today.getDay().equals(Color.FRIDAY)) {
            //todo
        }
        //编译报错保证编译检查安全
        //if (today.getDay() ==  Color.FRIDAY) {
            //todo
        //}
    }

    public Day getDay() {
        return day;
    }

    public void setDay(Day day) {
        this.day = day;
    }
}
enum Color {
    RED,GREEN,FRIDAY
}

使用场景与实例

  1. 在switch中使用
    public static boolean isWeekend(Day day) {
        switch (day) {
            case SATURDAY:
            case SUNDAY:
                return true;
            default:
                return false;
        }
    }
  1. 枚举类型增加属性和方法
public enum RepayMethod {
    
    BULLET_REPAYMENT(1, "一次性还款"),
    INTEREST(2, "先息后本"),
    EQUAL_INSTALLMENT(4, "等额本息"),
    EQUAL_PRINCIPAL(8, "等额本金");

    private Integer code;
    private String msg;

    private RepayMethod(Integer type, String msg) {
        this.code = type;
        this.msg = msg;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

}
  1. java8 lambda使用枚举
public class Loan {

    private Long id;

    private RepayMethod repayMethod;


    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public RepayMethod getRepayMethod() {
        return repayMethod;
    }

    public void setRepayMethod(RepayMethod repayMethod) {
        this.repayMethod = repayMethod;
    }



    public static List<Loan> groupByRepayMethod(List<Loan> list, RepayMethod repayMethod) {
        return list.stream().filter(loan -> repayMethod == loan.repayMethod).collect(Collectors.toList());
    }


}
  1. EnumSet
    EnumSet 是一种专门为枚举类型所设计的 Set 类型。与HashSet相比,由于使用了内部位向量表示,因此它是特定 Enum 常量集的非常有效且紧凑的表示形式。EnumSet 是抽象类,其有两个实现:RegularEnumSet (小于等于64个元素使用)、JumboEnumSet,选择哪一个取决于实例化时枚举中常量的数量。使用EnumSet的of方法来构建EnumSet。
    private  static EnumSet<RepayMethod> MULTIPLE_PERIOD_REPAY_METHOD = EnumSet.of(INTEREST,EQUAL_INSTALLMENT,EQUAL_PRINCIPAL);
    
    public static boolean isMultiplePeriod(RepayMethod repayMethod) {
        return MULTIPLE_PERIOD_REPAY_METHOD.contains(repayMethod);
    }
  1. EnumMap
    EnumMap是一个专门化的映射实现,用于将枚举常量用作键。与对应的 HashMap 相比,它是一个高效紧凑的实现,并且在内部表示为一个数组
    public static EnumMap<RepayMethod, List<Loan>> groupByRepayMethod(List<Loan> list) {
        EnumMap<RepayMethod, List<Loan>> map = new EnumMap(RepayMethod.class);
        for (Loan loan : list) {
            if (map.containsKey(loan.getRepayMethod())) {
                map.get(loan.getRepayMethod()).add(loan);
            } else {
                List<Loan> groupList = new ArrayList<>();
                groupList.add(loan);
                map.put(loan.getRepayMethod(),groupList);
            }
        }
        return map;
    }
  1. 使用枚举实现单例模式
public enum Singleton {
    INSTANCE;

    public void service() {
        //todo
    }
}
  1. 使用枚举实现策略模式(适用于处理逻辑较为简单的策略模式)
public enum RepayTypeStrategy {

    BULLET_REPAYMENT {
        @Override
        public void createLoanRepay(Loan loan) {
            //todo
        }
    },
    INTEREST {
        @Override
        public void createLoanRepay(Loan loan) {
          //todo
        }
    };

    public abstract void createLoanRepay(Loan loan);
    
}

相关原理

使用javap对编译好的枚举类字节码进行反编译得到如下信息,可以发现其继承自java.lang.Enum,其实现还是静态常量的方式实现的,EnumSet和EnumMap利用到了Enum的ordinal字段,具体详情可以查看源码。

Compiled from "RepayMethod.java"
public final class com.yueyang.se.enumeration.RepayMethod extends java.lang.Enum<com.yueyang.se.enumeration.RepayMethod> {
  public static final com.yueyang.se.enumeration.RepayMethod BULLET_REPAYMENT;
  public static final com.yueyang.se.enumeration.RepayMethod INTEREST;
  public static final com.yueyang.se.enumeration.RepayMethod EQUAL_INSTALLMENT;
  public static final com.yueyang.se.enumeration.RepayMethod EQUAL_PRINCIPAL;
  public static com.yueyang.se.enumeration.RepayMethod[] values();
  public static com.yueyang.se.enumeration.RepayMethod valueOf(java.lang.String);
  public java.lang.Integer getCode();
  public void setCode(java.lang.Integer);
  public java.lang.String getMsg();
  public void setMsg(java.lang.String);
  public static boolean isMultiplePeriod(com.yueyang.se.enumeration.RepayMethod);
  static {};
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272