引入
编写季节类(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;
}
@Override
public 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;
}
@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语句简洁,但是更加安全、灵活。
枚举案例之策略枚举
需求:按照学校不同部门和不同员工类别去计算工资
分析:校长(行政)、财务(行政)、班主任(行政)、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;//类型
private Salary(StaffType staffType) {//有参构造
this.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 StaffType
administration {//匿名内部类(静态内部类) 行政人员
@Override
public double countSalary(double baseSalary, int classHour, double teachingHourSubsidy,
double achievements) {
BigDecimal big1 = new BigDecimal(String.valueOf(baseSalary));//底薪
BigDecimal big2 = new BigDecimal(String.valueOf(achievements));//绩效
BigDecimal result = big1.add(big2);
return result.doubleValue();
}
},
teacher{
@Override
public double countSalary(double baseSalary, int classHour, double teachingHourSubsidy,
double achievements) {
BigDecimal big1 = new BigDecimal(String.valueOf(baseSalary));//底薪
BigDecimal big2 = new BigDecimal(String.valueOf(achievements));//绩效
BigDecimal big3 = new BigDecimal(String.valueOf(classHour));//课时
BigDecimal big4 = new BigDecimal(String.valueOf(teachingHourSubsidy));//课时费
BigDecimal 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集合中
EnumSet<Signal> signalSet = EnumSet.allOf(Signal.class);
for (Enum<Signal> en : signalSet) {
System.out.println(en);
}
//EnumMap的使用
EnumMap<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}
标签:code,String,int,double,EnumSet,状态机,枚举,public
From: https://blog.51cto.com/u_16154651/6466551