枚举
引入
编写季节类(Season),该类只有四个对象(spring,summer,autumn,winter)
概念
枚举(enum)全称为 enumeration, 是 JDK 1.5 中引入的新特性。
语法
1 2 3 4
| public enum Color{ RED,GREEN,BLUE; }
|
本质
尽管枚举看起来像是一种新的数据类型,实际上,枚举就是一种受限制的类,并且具有自己的方法。创建自己的enum类时,这个类继承自 java.lang.Enum。
1 2 3
| public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable{ ... }
|
特点
- 枚举就是一个受限制的类,默认继承Enum
- 枚举的第一行必须定义该枚举类型的对象
- 枚举类型对象默认添加: public static final 类型
- 枚举没有继承明确类(自定义枚举类默认继承Enum,Enum默认继承Object)
- 枚举类不能被继承
- 枚举里可以有构造方法、成员方法、静态方法、抽象方法
- 枚举可以实现接口
- 枚举里没有定义方法,可以在最后一个对象后面加逗号、分号或什么都不加
优势
枚举的方法
方法名 | 解释 |
---|
Enum.valueOf(ClassenumType, String name) | 根据字符串找到该枚举类中的对象 |
public static void values() | 获取该枚举类对象数组 |
public static void valueOf(String args0) | 根据字符串获取该枚举类中的对象 |
public final String name() | 获取该枚举对象名字 |
public final ClassgetDeclaringClass() | 获取枚举对象的枚举类型相对应的Class对象 |
public final int hashCode() | 获取该枚举对象的hash值 |
public final int compareTo(E o) | 两个枚举对象进行比较 |
public final boolean equals(Object other) | 比较两个枚举对象是否相同 |
枚举案例 - 状态机
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| enum Signal{RED, YELLOW, GREEN}
public class EnumTest {
public static void main(String[] args) { Scanner scan = new Scanner(System.in); System.out.println("请输入信号灯:RED,YELLOW,GREEN"); Signal signal = Signal.valueOf(scan.next()); String instruct = getTrafficInstruct(signal); System.out.println(instruct); scan.close(); }
public static String getTrafficInstruct(Signal signal) { String instruct = "信号灯故障"; switch (signal) { case RED: instruct = "红灯停"; break; case YELLOW: instruct = "黄灯请注意"; break; case GREEN: instruct = "绿灯行"; break; default: break; } return instruct; } }
|
枚举案例 - 错误码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public enum ErrorCodeEn { Ok(1,"成功"),ERROR_A(2,"错误A"),ERROR_B(3,"错误B"); private int code; private String description; ErrorCodeEn(){} ErrorCodeEn(int code,String description){ this.code = code; this.description = description; }
public int getCode() { return code; }
public String getDescription() { return description; } }
|
枚举案例 - 组织枚举
含义:可以将类型相近的枚举通过接口或类组织起来(但是一般用接口方式进行组织)
原因是:
Java接口在编译时会自动为enum类型加上public static修饰符;
Java类在编译时会自动为 enum 类型加上static修饰符;
就是说,在类中组织 enum,如果你不给它修饰为 public,那么只能在本包中进行访问。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| 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; }
@Override public int getCode() { return code; } @Override public 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; }
@Override public int getCode() { return code; } @Override public String getDescription() { return description; } }
}
interface INumberEnum { int getCode(); String getDescription(); }
|
枚举案例 - 策略枚举
优点:这种枚举通过枚举嵌套枚举的方式,将枚举常量分类处理。
这种做法虽然没有switch语句简洁,但是更加安全、灵活。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| public enum Salary { JAVA(SalaryType.TEACHER), HTML(SalaryType.TEACHER), PYTHON(SalaryType.TEACHER), PRINCIPAL(SalaryType.ADMINISTRATION); private final SalaryType salaryType; Salary(SalaryType salaryType){ this.salaryType = salaryType; } double getSalary(double baseSalary,int classHour,double teachingHourSubsidy,double achievements){ return salaryType.getSalary(baseSalary, classHour, teachingHourSubsidy, achievements); } private enum SalaryType { TEACHER { @Override double getSalary(double baseSalary, int classHour, double teachingHourSubsidy, double achievements) { return baseSalary + classHour*teachingHourSubsidy + achievements; } }, ADMINISTRATION { @Override double getSalary(double baseSalary, int classHour, double teachingHourSubsidy, double achievements) { return baseSalary + achievements; } }; abstract double getSalary(double baseSalary,int classHour,double teachingHourSubsidy,double achievements); } }
|
枚举工具类 - EnumSet 和 EnumMap
Java 中提供了两个方便操作enum的工具类——EnumSet 和 EnumMap。
EnumSet :枚举类型的高性能 Set实现。它要求放入它的枚举常量必须属于同一枚举类型。
EnumMap :专门为枚举类型量身定做的 Map 实现。虽然使用其它的 Map 实现(如HashMap)也能完成枚举类型实例到值得映射,但是使用 EnumMap 会更加高效,因为它只能接收同一枚举类型的实例作为键值,并且由于枚举类型实例的数量相对固定并且有限,所以 EnumMap 使用数组来存放与枚举类型对应的值。这使得 EnumMap 的效率非常高。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class EnumTest { public static void main(String[] args) { EnumSet<Signal> signalSet = EnumSet.allOf(Signal.class); for (Enum<Signal> en : signalSet) { System.out.println(en); } EnumMap<Signal,Object> enumMap = new EnumMap<>(Signal.class); enumMap.put(Signal.RED, "红灯"); enumMap.put(Signal.YELLOW, "黄灯"); enumMap.put(Signal.GREEN, "绿灯"); 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}
|