Java枚舉

簡(jiǎn)介

枚舉類型是一種使用一組預(yù)定義的常量表示的一種特殊數(shù)據(jù)類型。enum關(guān)鍵字在 java5 中引入,所有的枚舉類默認(rèn)都集成自java.lang.Enum類。

//基本寫(xiě)法
public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY 
}

枚舉與常量比較

  • 優(yōu)點(diǎn)
    1. 可讀性更高
    2. 編譯時(shí)檢查減少代碼錯(cuò)誤(相對(duì)于基本數(shù)據(jù)類型的常量)
    3. 表現(xiàn)力更強(qiáng)(相對(duì)于基本數(shù)據(jù)類型的常量)
    4. 使用 == 對(duì)枚舉進(jìn)行比較提供編譯時(shí)和運(yùn)行時(shí)的安全性
  • 缺點(diǎn)
    1. 增加類的數(shù)目
    2. 數(shù)據(jù)轉(zhuǎn)換麻煩
public class Date {

    private Day day;

    public static void main(String[] args) {
        Date today = new Date();
        //可能會(huì)出NPE
        if (today.getDay().equals(Day.FRIDAY)) {
            //todo
        }
        //使用==保證運(yùn)行時(shí)安全
        if (today.getDay() == Day.FRIDAY) {
            //todo
        }
       //比較會(huì)得到true
        if (today.getDay().equals(Color.FRIDAY)) {
            //todo
        }
        //編譯報(bào)錯(cuò)保證編譯檢查安全
        //if (today.getDay() ==  Color.FRIDAY) {
            //todo
        //}
    }

    public Day getDay() {
        return day;
    }

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

使用場(chǎng)景與實(shí)例

  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 是一種專門(mén)為枚舉類型所設(shè)計(jì)的 Set 類型。與HashSet相比,由于使用了內(nèi)部位向量表示,因此它是特定 Enum 常量集的非常有效且緊湊的表示形式。EnumSet 是抽象類,其有兩個(gè)實(shí)現(xiàn):RegularEnumSet (小于等于64個(gè)元素使用)、JumboEnumSet,選擇哪一個(gè)取決于實(shí)例化時(shí)枚舉中常量的數(shù)量。使用EnumSet的of方法來(lái)構(gòu)建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是一個(gè)專門(mén)化的映射實(shí)現(xiàn),用于將枚舉常量用作鍵。與對(duì)應(yīng)的 HashMap 相比,它是一個(gè)高效緊湊的實(shí)現(xiàn),并且在內(nèi)部表示為一個(gè)數(shù)組
    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. 使用枚舉實(shí)現(xiàn)單例模式
public enum Singleton {
    INSTANCE;

    public void service() {
        //todo
    }
}
  1. 使用枚舉實(shí)現(xiàn)策略模式(適用于處理邏輯較為簡(jiǎn)單的策略模式)
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);
    
}

相關(guān)原理

使用javap對(duì)編譯好的枚舉類字節(jié)碼進(jìn)行反編譯得到如下信息,可以發(fā)現(xiàn)其繼承自java.lang.Enum,其實(shí)現(xiàn)還是靜態(tài)常量的方式實(shí)現(xiàn)的,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 {};
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容