java入门基础八(枚举)

12. 枚举

​ 有些特殊类在编写时,我们明确知道他的对象存在,更愿意在创建类时就将这些对象实现,也不允许此类被其他类继承,同时让这些特定的对象唯一。

如:季节类(Season),该类只有四个对象(spring,summer,autumn,winter)

​ 交通信号灯类(TrafficLights),该类只有三个对象(red,yellow,green)

在 JDK1.5 开始,引入枚举(enum)全称为 enumeration。

12.1 语法规则

public enum Season{
    //首行必须定义对象,这些对象默认添加 public static final Season
   spring,summer,autumn,winter;
    
    //其后添加属性和方法。
}

注:1.首行必须定义对象,对象之间使用“,”(英文逗号)分隔开。

​ 2.对象定义结束使用“;”(英文分号)结尾。

​ 3.若不想先定义对象,可以直接使用;隔开,在其后写属性和方法。

​ 4.枚举类的构造方法为private,表示私有,不可被外部调用,即是:外部不能创建对象。

​ 5.枚举类默认的添加final,表示不可被继承,但可以实现接口。

​ 6.枚举中的方法可以有:构造、成员、静态、抽象。

​ 7.枚举里没有定义方法,可以在最后一个对象后面加逗号、分号或什么都不加。

12.2 枚举的本质

​ 尽管枚举看起来像是一种新的数据类型,但实际上,枚举是一种受限制的类,并且具有自己的方法。

​ 在创建自己的enum类时,这个类继承自 java.lang.Enum。

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

12.3 枚举的优势

  • 增强代码可读性

  • 枚举型可直接与数据库交互

  • switch语句优势

  • 编译优势

    (枚举类编译时,没有把常量值编译到代码中,即使常量值发生改变,也不会影响引用常量的类 )

  • 将常量组织起来,统一管理

  • 去除equals两者判断 由于常量值地址唯一,使用枚举可以直接通过“==”进行两个值之间的对比,性能会有所提高

12.4 枚举的方法

方法名解释
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 enum Season {
	spring("春天","春雨蒙蒙"),
	summer("夏天","大汗淋漓"),
	autumn("秋天","硕果累累"),
	winter("冬天","银装素裹");
	
	
	private String name;
	private String info;
	
	private Season(String name, String info) {
		this.name = name;
		this.info = info;
	}
	private Season() {
		
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getInfo() {
		return info;
	}
	public void setInfo(String info) {
		this.info = info;
	}
	@Override
	public String toString() {
		return name + " -- " + info;
	}
}

测试方法:

public static void main(String[] args) {
    
    //根据字符串找到该枚举类中的对象
    Season season1 = Enum.valueOf(Season.class, "spring");
    System.out.println(season1);  //春天 -- 春雨蒙蒙

    //获取该枚举类对象数组
    Season[] values = Season.values();
    for (Season season : values) {
        System.out.println(season);
    }
    //根据字符串获取该枚举类中的对象
    Season valueOf = Season.valueOf("autumn");
    System.out.println(valueOf);   //秋天 -- 硕果累累

    //根据对象获取出对象名
    String name = valueOf.name();
    System.out.println(name);    //autumn

    //获取枚举对象的枚举类型相对应的Class对象
    Class<Season> declaringClass = valueOf.getDeclaringClass();
    System.out.println(declaringClass);  class com.dream.test04.Season
}

12.5 枚举案例

12.5.1 状态机(switch优势)

import java.util.Scanner;

public class Test_4 {

	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 intruct = getTrafficInstruct(signal);
		System.out.println(intruct);

	}
	public static String getTrafficInstruct(Signal signal){
		String intruct ="信号灯故障"; 
		switch(signal){
		case RED:
			intruct="当前红灯,停";
			break;
		case YELLOW:
			intruct="当前黄灯,注意安全";
			break;
		case GREEN:
			intruct="当前绿灯,行";
			break;
		default :
			break;
		}
		return intruct;
	}
}

//定义枚举类Signal
enum Signal{RED,YELLOW,GREEN}

12.5.2 错误码

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;
	}
}

12.5.3 组织枚举

含义:可以将类型相近的枚举通过接口或类组织起来(但是一般用接口方式进行组织)

原因是:

​ 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();
}

12.5.4 策略枚举

优点:这种枚举通过枚举嵌套枚举的方式,将枚举常量分类处理。

这种做法虽然没有switch语句简洁,但是更加安全、灵活。

import java.math.BigDecimal;

public class Test_5 {

	public static void main(String[] args) {
		double salary_java = Salary.java.getSalary(1000, 20, 80, 500);
		System.out.println("java教师的工资:"+salary_java);
		double salary_python = Salary.python.getSalary(1200, 25, 80, 600);
		System.out.println("Python教师的工资:"+salary_python);
		double salary_principal = Salary.principal.getSalary(5000, 0, 0, 5000);
		System.out.println("校长的工资为:"+salary_principal);
		double salary_reception = Salary.reception.getSalary(1500, 0, 0, 500);
		System.out.println("前台的工资为:"+salary_reception);
	}

}
enum Salary{
	java(StaffType.teacher),//java部门
	python(StaffType.teacher),//python部门
	principal(StaffType.administrative),//总经办(校长)部门
	reception(StaffType.administrative);//前台部门
	
	private StaffType staffType;
	
	private Salary(StaffType staffType) {
		this.staffType = staffType;
	}
	/**
	 * 计算月工资
	 * @param baseSalary  基本工资
	 * @param classHour  课时
	 * @param teachingHourSubsidy 课时费
	 * @param achievements  绩效
	 * @return  工资(double)
	 */
	public double getSalary(double baseSalary, int classHour, double teachingHourSubsidy,
			double achievements){
		return staffType.calculationSalary(baseSalary, classHour, teachingHourSubsidy, achievements);
	}
	enum StaffType{
        //创建匿名内部类
		administrative{

			@Override
			public double calculationSalary(double baseSalary, int classHour, double teachingHourSubsidy,
					double achievements) {
				BigDecimal bigBaseSalary = new BigDecimal(String.valueOf(baseSalary));
				BigDecimal bigAchievements = new BigDecimal(String.valueOf(achievements));
				BigDecimal add = bigBaseSalary.add(bigAchievements);
				return add.doubleValue();
			}
			
		},
        //创建匿名内部类
		teacher{

			@Override
			public double calculationSalary(double baseSalary, int classHour, double teachingHourSubsidy,
					double achievements) {
				BigDecimal bigBaseSalary = new BigDecimal(String.valueOf(baseSalary));
				BigDecimal bigClassHour = new BigDecimal(String.valueOf(classHour));
				BigDecimal bigTeachingHourSubsidy = new BigDecimal(String.valueOf(teachingHourSubsidy));
				BigDecimal bigAchievements = new BigDecimal(String.valueOf(achievements));
				BigDecimal add = bigBaseSalary.add(bigAchievements).add(bigClassHour.multiply(bigTeachingHourSubsidy));
				return add.doubleValue();
			}
			
		};
        //枚举中的抽象方法,留给匿名内部类实现。
		public abstract double calculationSalary(double baseSalary,int classHour,double teachingHourSubsidy,double achievements);
	}
}
/*
java教师的工资:3100.0
Python教师的工资:3800.0
校长的工资为:10000.0
前台的工资为:2000.0
*/

12.6 枚举工具类 - 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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值