0
点赞
收藏
分享

微信扫一扫

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

引入

编写季节类(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}

举报

相关推荐

0 条评论