java入门----枚举
概念
枚举(enum)全程为enumeration ,是JDK1.5中引入的新特性
语法
public enum Color{
//默认添加 public static final Color
RED,GREEN,BLUE;
}
本质
枚举就是一种受限制的类,并且有自己的方法。创建自己的enum类时,这个类继承自java.lang.Enum
注意:
枚举是一个受限制的类,默认继承Enum
枚举的第一行必须定义该枚举类型的对象
枚举类型对象默认添加:public static final
枚举没有继承明确类(自定义枚举类默认继承Enum,Enum默认继承Object)
枚举类不能被继承
枚举里可以构造方法、成员方法、静态方法、抽象方法
枚举可以实现接口
枚举里没有定义方法时,可以在最后一个对象后面加逗号、分号或者什么都不加
优点:
增强代码可读性
枚举型可直接与数据库交互
switch语句优势
编译优势:(枚举类编译时,没有把常量值编译到代码中,即使常量值发生改变,也不会影响引用常量的类 )
将常量组织起来,统一管理
去除equals两者判断 由于常量值地址唯一,使用枚举可以直接通过“==”进行两个值之间的对比,性能会有所提高
案例:编写一个季节类,类里只有春夏秋冬四个对象
package com.dream.enum01;
public class Season {
//自行构造对象,并final修饰,对象不能被修改
public static final Season spring = new Season("春天", "万物复苏");
public static final Season summer = new Season("夏天", "汗如雨下");
public static final Season autumn = new Season("秋天", "秋高气爽");
public static final Season winter = new Season("冬天", "寒风凛冽");
private String name;
private String info;
//构造方法私有化,不让外界新建对象
private Season() {
}
//构造方法私有化,不让外界新建对象
private Season(String name, String info) {
this.name = name;
this.info = info;
}
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 "Season [name=" + name + ", info=" + info + "]";
}
}
package com.dream.enum01;
public class Test01 {
public static void main(String[] args) {
/**
* 枚举引入:
* 编写季节类(Season),该类只有四个对象(spring,summer,autumn,winter)
*/
System.out.println(Season.spring);
System.out.println(Season.summer);
System.out.println(Season.autumn);
System.out.println(Season.winter);
}
}
Season [name=春天, info=万物复苏]
Season [name=夏天, info=汗如雨下]
Season [name=秋天, info=秋高气爽]
Season [name=冬天, info=寒风凛冽]
使用枚举类
package com.dream.enum02;
//底层实现:public class Season extends Enum
public enum Season{
//默认:public static final Season
spring("春天","春雨绵绵"),
summer("夏天","大汗淋漓"),
autumn("秋天","硕果累累"),
winter("冬天","银装素裹");
private String name;
private String info;
private Season() {
}
private Season(String name, String info) {
this.name = name;
this.info = info;
}
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;
}
}
package com.dream.enum02;
public class Test01 {
public static void main(String[] args) {
/**
* 枚举引入:
* 编写季节类(Season),该类只有四个对象(spring,summer,autumn,winter)
*
* 使用枚举解决这个需求
*/
System.out.println(Season.spring);
System.out.println(Season.summer);
System.out.println(Season.autumn);
System.out.println(Season.winter);
}
}
春天 -- 春雨绵绵
夏天 -- 大汗淋漓
秋天 -- 硕果累累
冬天 -- 银装素裹
枚举的常用方法
package com.dream.enum03;
public class Test01 {
public static void main(String[] args) {
/**
* 知识点:枚举的常用方法
*/
//通过字符串获取到枚举类中的对象
Season season1 = Enum.valueOf(Season.class, "spring");
System.out.println(season1);
//获取到Season枚举类中所有的对象
Season[] values = Season.values();
for (Season season : values) {
System.out.println(season);
}
//通过字符串获取到枚举类中的对象
Season season2 = Season.valueOf("summer");
System.out.println(season2);
//获取到枚举对象的名字
String name = season2.name();
System.out.println(name);
//获取Season枚举类字节码文件对象
Class<Season> c = season2.getDeclaringClass();
System.out.println(c);
}
}
春天 -- 春雨绵绵
春天 -- 春雨绵绵
夏天 -- 大汗淋漓
秋天 -- 硕果累累
冬天 -- 银装素裹
夏天 -- 大汗淋漓
summer
class com.dream.enum03.Season
案例:状态机
package com.dream.enum04;
import java.util.Scanner;
public class Test01 {
public static void main(String[] args) {
/**
* 枚举案例 - 状态机
*/
Scanner scan = new Scanner(System.in);
System.out.println("请输入信号灯:RED, YELLOW, GREEN");
String next = scan.next();
Signal signal = Signal.valueOf(next);
switch (signal) {
case RED:
System.out.println("红灯停");
break;
case YELLOW:
System.out.println("黄灯请注意");
break;
case GREEN:
System.out.println("绿灯行");
break;
}
scan.close();
}
}
enum Signal{RED, YELLOW, GREEN}
请输入信号灯:RED, YELLOW, GREEN
RED
红灯停
案例:错误码
public enum ErrorCodeEn {
Ok(1,"成功"),ERROR_A(2,"错误A"),ERROR_B(3,"错误B");
private int code;//状态码
private String info;//状态描述
ErrorCodeEn(){}
ErrorCodeEn(int code,String info){
this.code = code;
this.info = info;
}
public int getCode() {
return code;
}
public String getInfo() {
return info;
}
}
组织枚举
含义:可以将类型相近的枚举通过接口或类组织起来(但是一般用接口方式进行组织)
原因是:
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语句简洁,但是更加安全、灵活。
package com.Xu.MyEnum;
public enum CalculatingArea {//计算面积
triangle(Area.TRIANGLE),//三角形
rectangular(Area.RECTANGULAR);//矩形
private final Area area;
CalculatingArea(Area area) {
this.area = area;
}
double getCalculatingArea(int length,int high) {
return area.count(length,high);
}
private enum Area{
TRIANGLE{//三角形
@Override
double count(int length,int high) {//重写计算方式
return length*high/2;
}
},
RECTANGULAR{//矩形
@Override
double count(int length,int high) {//重写计算方式
return length*high;
}
};
abstract double count(int length,int high);//三角形和矩形的面积计算方法不同,使用抽象类重写
}
}
package com.Xu.MyEnum;
public class Test {
public static void main(String[] args) {
double d1 = CalculatingArea.triangle.getCalculatingArea(4, 5);//三角形面积
double d2 = CalculatingArea.rectangular.getCalculatingArea(4, 5);//矩形面积
System.out.println("三角形面积:"+d1);
System.out.println("矩形面积:"+d2);
}
}
10.0
20.0
枚举工具类 — 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}