当前位置: 首页 > 图灵资讯 > 技术篇> 枚举的方法、枚举案例 - 状态机、组织枚举、策略枚举、枚举工具类 - EnumSet 和 EnumMap

枚举的方法、枚举案例 - 状态机、组织枚举、策略枚举、枚举工具类 - EnumSet 和 EnumMap

来源:图灵教育
时间:2023-06-13 09:21:00

引入

编写季节类(Season),这一类只有四个对象(spring,summer,autumn,winter)

概念

枚举(enum)全称为 enumeration, 是 JDK 1.5 介绍的新特性。

语法

public enum Color{    ///默认添加 public static final    RED,GREEN,BLUE;}

本质

虽然枚举看起来像一种新的数据类型,但事实上,枚举是一个有限的类别,有自己的方法。当创建自己的enum类别时,这个类别继承自己 java.lang.Enum。

public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable{    ...}

特点
  • 枚举是一个有限的类别,默认继承Enum
  • 枚举的第一行必须定义枚举类型的对象
  • 默认添加枚举类型对象: public static final 类型
  • 枚举没有明确的继承类别(自定义枚举类默认继承Enum,Enum默认继承Object)
  • 枚举类不能继承
  • 结构方法、成员方法、静态方法、抽象方法可用于枚举
  • 枚举可以实现接口
  • 枚举中没有定义方法,可以在最后一个对象后面加逗号、分号或者什么都不加
优势
  • 提高代码可读性
  • 枚举类型可以直接与数据库交互
  • switch语句优势
  • 编译优势(枚举类编译时,常量值没有编译到代码中,即使常量值发生变化,也不会影响引用常量类 )
  • 组织常量,统一管理
  • 判断去除equals 由于常量值地址是唯一的,两个值之间的对比可以通过“==”直接使用枚举,性能会提高
枚举的方法

方法名

解释

Enum.valueOf(Class enumType, String name)

根据字符串在枚举类中找到对象

public static void values()

获得枚举对象数组

public static void valueOf(String args0)

枚举类中的对象根据字符串获取

public final String name()

获取枚举对象的名称

public final Class getDeclaringClass()

获得枚举对象的枚举类型对应于Class对象

public final int hashCode()

获得枚举对象的hash值

public final int compareTo(E o)

两个枚举对象进行比较

public final boolean equals(Object other)

比较两个枚举对象是否相同

枚举案例 - 状态机

public class Test01 {/** * 知识点:枚举案例状态机 * 什么是状态机(即引入枚举,根据不同的枚举可以做很多功能,用switch判断枚举) *  信号灯 */public static void main(String[] args) {Scanner scan = new Scanner(System.in);System.out.println(“请选择信号灯:RED,YELLOW,GREEN");String str = scan.next();Signal signal = Signal.valueOf(str );String trafficInstruct = getTrafficInstruct(signal);System.out.println(trafficInstruct);scan.close();}public static String getTrafficInstruct(Signal signal){String trafficInstruct = “信号灯故障”;switch(signal){case RED:trafficInstruct = "红灯停";break;case YELLOW:trafficInstruct = 请注意“黄灯”;break;case GREEN:trafficInstruct = "绿灯行";break;}return trafficInstruct;}}

枚举

public enum Signal {RED,YELLOW,GREEN;}

枚举案例 - 错误码

public class Test01 {/** * 知识点:枚举案例错码 */ public static void main(String[] args) {System.out.println(AddCode.ERR_01);System.out.println(AddCode.ERR_02);System.out.println(AddCode.OK);}}

枚举错误码

public enum AddCode {ERR_01(-1)“添加失败 - 学生信息不合法”),ERR_02(-2,“重复学生信息违法”),OK(1,“成功添加”);private int code;private String message;private AddCode() {// TODO Auto-generated constructor stub}private AddCode(int code, String message) {this.code = code;this.message = message;//错误信息}public int getCode() {return code;}public void setCode(int code) {this.code = code;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}@Overridepublic String toString() {return message;}}

枚举案例 - 组织枚举

含义:类似类型的枚举可以通过接口或类组织(但通常通过接口组织)

原因是:

Java接口在编译过程中会自动添加enum类型和public static修饰符;

Java类在编译时会自动 enum static修饰符的类型;

也就是说,在类中组织 enum,假如你不给它修饰 public,然后只能访问这个包。

public interface IErrorCode {enum LoginErrorCodeEn implements INumberEnum{OK(1,“成功登录”),ERROR_A(-1,“验证码错误”),ERROR_B(-2,密码错误),ERROR_C(-3,“用户已登录”;private int code;private String description;LoginErrorCodeEn(int code,String description){this.code = code;this.description = description;}@Overridepublic int getCode() {return code;}@Overridepublic String getDescription() {return description;}}enum RigsterErrorCodeEn implements INumberEnum{OK(1,“成功注册”),ERROR_A(-1,“账号已存在”);private int code;private String description;RigsterErrorCodeEn(int code,String description){this.code = code;this.description = description;}@Overridepublic int getCode() {return code;}@Overridepublic String getDescription() {return description;}}}interface INumberEnum {int getCode();String getDescription();}

枚举案例 - 策略枚举

优点:这种枚举通过枚举嵌套枚举对枚举常量进行分类。

虽然这种做法不像switch那样简洁,但它更安全、更灵活。

枚举案例的策略枚举

工资按学校不同部门和不同员工类别计算

分析:校长(行政)、财务(行政)、班主任(行政)、Java(老师)、Python(老师)、UI(老师)

public class Test01 {public static void main(String[] args) {System.out.println(Salary.finance.getSalary(2000, 0, 0,2000));System.out.println(Salary.java.getSalary(2000, 20, 15, 1500));}}

public enum Salary {principal(StaffType.administration), finance(StaffType.administration), classTeacher(StaffType.administration),java(StaffType.teacher),python(StaffType.teacher),ui(StaffType.teacher),;private StaffType staffType;///类型privateteprivate Salary(StaffType staffType) {///有参与结构thiss.staffType = staffType;}public double getSalary(double baseSalary, int classHour, double teachingHourSubsidy,double achievements){return staffType.countSalary(baseSalary, classHour, teachingHourSubsidy, achievements);}//员工类别(为不同类别的员工设定计算工资的方法)enum StaffType{//枚举内部类/////匿名内部类对象 -- 可以在底层实现 class StaffType$1 extends StaffTypeadministration {//匿名内部类(静态内部类)  行政人员@Overridepublic double countSalary(double baseSalary, int classHour, double teachingHourSubsidy,double achievements) {BigDecimal big1 = new BigDecimal(String.valueOf(baseSalary));///底薪BigDecimall big2 = new BigDecimal(String.valueOf(achievements));///// result = big1.add(big2);return result.doubleValue();}},teacher{@Overridepublic double countSalary(double baseSalary, int classHour, double teachingHourSubsidy,double achievements) {BigDecimal big1 = new BigDecimal(String.valueOf(baseSalary));///底薪BigDecimall big2 = new BigDecimal(String.valueOf(achievements));///// big3 = new BigDecimal(String.valueOf(classHour));///课时BigDecimal big4 = new BigDecimal(String.valueOf(teachingHourSubsidy));///课时费BigDecimall result = big3.multiply(big4).add(big1).add(big2);return result.doubleValue();}};/** * 计算工资 * @param baseSalary 底薪 * @param classHour  课时 * @param teachingHourSubsidy  课时费 * @param achievements  绩效 * @return *///baseSalary-底薪 classHour-课时 teachingHourSubsidy-课时费 achievements-性能public abstract double countSalary(double baseSalary,int classHour,double teachingHourSubsidy,double achievements);}}

枚举工具类 - EnumSet 和 EnumMap

Java 提供了两种方便操作enum的工具类——EnumSet 和 EnumMap。

EnumSet :高性能枚举类型 实现Set。它要求放入其中的枚举常量必须属于相同类型的枚举。EnumMap :专门为枚举类型量身定制 Map 实现。虽然使用其他的 Map 实现(如Hashmap)也可以完成值得映射的枚举类型实例,但使用 EnumMap 它会更有效率,因为它只能接收同一枚举类型的例子作为键值,而且由于枚举类型的例子数量相对固定和有限,因此 EnumMap 用数组存储与枚举类型相对应的值。这使得 EnumMap 效率很高。

public class EnumTest {public static void main(String[] args) 使用{///Enumset        ///将Signal枚举中的所有对象提取到Set集合中的Enumsetet中<Signal> signalSet = EnumSet.allOf(Signal.class);for (Enum<Signal> en : signalSet) {System.out.println(en);}///Enummmap使用Enummmap<Signal,Object> enumMap = new EnumMap<>(Signal.class);enumMap.put(Signal.RED, "红灯");enumMap.put(Signal.YELLOW, "黄灯");enumMap.put(Signal.GREEN, "绿灯");        ////将所有映射对象提取到Set集合Set<Entry<Signal, Object>> entrySet = enumMap.entrySet();for (Entry<Signal, Object> entry : entrySet) {Signal key = entry.getKey();Object value = entry.getValue();System.out.println(key + " -- " + value);}}}enum Signal{RED, YELLOW, GREEN}