枚举
定义
关键字enum可以将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序组件使用。
入门
//定义一个普通枚举
enum Shrubbery {GROUND, CRAWLING, HANGING}
public class EnumClass {
public static void main(String[] args) {
for (Shrubbery s : Shrubbery.values()) {
//输出枚举的名称和索引下标
System.out.println(s + " ordinal: " + s.ordinal());
//重写了compareTo方法,输入当前枚举下标与指定枚举下标的差值
System.out.println(s.compareTo(Shrubbery.CRAWLING));
//equals方法与==符号作用相等
System.out.println(s.equals(Shrubbery.CRAWLING));
System.out.println(s == Shrubbery.CRAWLING);
//所属的类
System.out.println(s.getDeclaringClass());
//输出实例声明的名字
System.out.println(s.name());
System.out.println("-------------");
}
//通过String数组,获取枚举实例,前提是该String必须在枚举中,否则报错
for (String s : "HANGING CRAWLING GROUND".split(" ")) {
Shrubbery shrubbery = Enum.valueOf(Shrubbery.class, s);
System.out.println(shrubbery + "ordinal: " + shrubbery.ordinal());
}
}
}
构造函数创建枚举
需要注意的一个地方:在枚举中定义方法和属性,必须在枚举实例声明后才能定义。否则编译器报错。
public enum OzWitch {
//通过私有构造函数,构建枚举
WEST("this is WEST"),
NORTH("this is NORTH"),
EAST("this is EAST"),
SOUTH("this is SOUTH");
//重点:只能在枚举实例之后定义方法和属性
private String description;
//私有构造函数
private OzWitch(String description){
this.description = description;
}
public String getDescription() {
return description;
}
public static void main(String[] args) {
for (OzWitch o : OzWitch.values()){
//循环遍历,并获取description字段信息
System.out.println(o+":"+o.getDescription());
}
}
}
switch中使用
枚举具备整数值的次序,且可通过ordinal()方法取得次序,所以可以在switch中使用枚举
//定义枚举
enum Signal{GREEN,YELLOW,RED}
public class SwitchEnum {
//默认的枚举值
Signal color = Signal.RED;
public void change(){
//通过枚举就可以直接在枚举中使用,而不用调用ordinal()方法
//显然编译器已经做了优化
switch (color){
case RED:color = Signal.GREEN;break;
case GREEN:color = Signal.YELLOW;break;
case YELLOW:color = Signal.RED;break;
}
}
@Override
public String toString() {
return "SwitchEnum{" +
"color=" + color +
'}';
}
public static void main(String[] args) {
SwitchEnum s = new SwitchEnum();
for (int i = 0; i < 7; i++) {
System.out.println(s);
s.change();
}
}
}
随机读取
enum Activity{A,B,C,D,E,F,G}
public class EnumRandom{
//定义随机对象
private static Random random = new Random(47);
// <T extends Enum<T>> 代表枚举对象
public static <T extends Enum<T>> T random(Class<T> ec){
return random(ec.getEnumConstants());
}
//重载random方法,目的是为了不破坏Enum的操作
public static <T> T random(T[] values){
return values[random.nextInt(values.length)];
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
//直接传入枚举类,就可以实现随机读取了
System.out.println(random(Activity.class));
}
}
}
设计模式
单例模式
public class Singleton {
//使用枚举,构建单例模式
private Singleton() {
}
private enum SingletonEnum {
//申明唯一一个单利枚举
singletonEnum;
//申请单利对象
private Singleton singleton;
SingletonEnum(){
//在枚举的构造函数中,获取对象实例
singleton = new Singleton();
}
//返回单例对象
public Singleton getInstance(){
return singleton;
}
}
public static Singleton getInstance(){
//直接返回枚举的getInstance方法,即可获取单例对象
return SingletonEnum.singletonEnum.getInstance();
}
}
策略模式
public class Strategy {
public enum ROLE{
//在枚举中实现抽象函数
ADMIN{
@Override
public void speak(){
System.out.println("我是管理员");
}
},
USER{
@Override
public void speak(){
System.out.println("我是用户");
}
},
VIP{
@Override
public void speak(){
System.out.println("我是vip");
}
};
//声明一个抽象方法,目的是为了使角色有一个统一的行为
public abstract void speak();
}
public static void main(String[] args) {
//直接使用即可
ROLE.ADMIN.speak();
ROLE.USER.speak();
ROLE.VIP.speak();
}
}
总结
枚举在实际开发中运用的场景不多。在我所参与的项目中,枚举其实是作为业务表中的状态字段映射,通过使用枚举,不再使用硬编码。比如,状态字段state,有三种状态 0:未完成;2:完成中;2:已完成,判断状态时,不再用0/1/2去判断,而使用枚举定义的key和value去判断。这样在代码的可读行和维护性上,提高了很多。
public enum DemoEum {
END(0, "未完成"),
DOING(1,"完成中")
FINISH(2,"已完成")
;
private Integer key;
private String value;
public Integer getKey() {
return key;
}
public void setKey(Integer key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
DemoEum (Integer key, String value) {
this.key = key;
this.value = value;
}
未使用枚举时
....
if(state == 0){//未完成。。。。
}else if(state == 1){//完成中。。。。
}
....
使用枚举
....
if(state == DemoEum.END.getKey()){//未完成。。。。
}else if(state == DemoEum.DOING.getKey()){//完成中。。。。
}
....

浙公网安备 33010602011771号