美文网首页
Java枚举

Java枚举

作者: yueming15899 | 来源:发表于2020-05-26 16:46 被阅读0次

简介

枚举类型是一种使用一组预定义的常量表示的一种特殊数据类型。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 {};
}

相关文章

  • 枚举

    枚举 wiki Java的枚举类型用法介绍 深入理解Java枚举类型(enum) 为什么要用enum? 学习计划 ...

  • Java枚举

    Java中的每个枚举都是java.lang.Enum的final子类,枚举类中的每个枚举常量都是该枚举类的一个实例...

  • Kotlin基础---枚举类

    Java的枚举 Kotlin的枚举 枚举是极少数Kotlin声明比Java使用了更多的关键字的例子Kotlin用了...

  • 枚举学习

    java enum枚举类 enum(枚举)类介绍 **java枚举类是一组预定义常量的集合,使用enum关键字声明...

  • Java枚举类

    枚举其实是个特殊的 Java 类,创建枚举需用enum关键字,枚举类都是java.lang.Enum的子类,jav...

  • Java枚举总结

    Java枚举总结 枚举类型比较简单,下面两个文章讲的比较清楚: Java 枚举(enum) 详解7种常见的用法 深...

  • [Kotlin Tutorials 5] 枚举和Sealed C

    枚举和Sealed Class 枚举 首先, Kotlin和Java一样, 也是有枚举类型的: 枚举类型还可以实现...

  • Java 枚举

    问:Java 枚举类比较用 == 还是 equals,有什么区别? 答:java 枚举值比较用 == 和 equa...

  • 店铺注册的dto(页面数据层)

    ShopExecution.java ShopStateEnum.java使用枚举类表示

  • Java枚举

    枚举 普通方式定义(int枚举模式) 枚举方式 Enum抽象类常见方法 Enum是所有 Java 语言枚举类型的公...

网友评论

      本文标题:Java枚举

      本文链接:https://www.haomeiwen.com/subject/fuyuahtx.html