枚举Enum的使用

1、为什么使用枚举?

以博客网站为例,文章有三种状态:草稿、审核和发布,可将其定义为静态常量:

1public class BlogStatus{ 2 public static final int Draft = 1; // 草稿 3 public static final int Review = 2; // 审核 4 public static final int Published = 3; // 发布 5}

对于一个判断函数judgeBlogStatus()而言,输入参数没有类型的约束,因此传入任意一个int值都是可以的,编译器也不会提出任何警告。

1public void judgeBlogStatus(int status){ 2 ... 3}

此时枚举类型就可以严谨地约束:

1public enum BlogStatus{ 2 Draft, Review, Published 3}
1public void judgeBlogStatus(BlogStatus status){ 2 ... 3}

2、如何使用Enum

以后台管理系统为例,使用枚举Enum定义用户角色:

1public enum UserRole{ 2 ROLE_ROOT_ADMIN; // 系统管理员 3 ROLE_ORDER_ADMIN; // 订单管理员 4 ROLE_NORMAL; // 普通用户 5}

枚举的基本用法:

1UserRole role1 = UserRole.ROLE_ROOT_ADMIN; 2UserRole role2 = UserRole.ROLE_ORDER_ADMIN; 3UserRole role3 = UserRole.ROLE_NORMAL; 4 5// values()方法:返回所有枚举常量的数组集合 6for(UserRole role : UserRole.values()){ 7 System.out.println(role); 8} 9// 打印: 10// ROLE_ROOT_ADMIN 11// ROLE_ORDER_ADMIN 12// ROLE_NORMAL 13 14// ordinal()方法:返回枚举常量的序数,注意从0开始 15System.out.println( role1.ordinal() ); // 打印0 16System.out.println( role2.ordinal() ); // 打印1 17System.out.println( role3.ordinal() ); // 打印2 18 19// compareTo()方法:枚举常量间的比较 20System.out.println( role1.compareTo(role2) ); //打印-1 21System.out.println( role2.compareTo(role3) ); //打印-2 22System.out.println( role1.compareTo(role3) ); //打印-2 23 24// name()方法:获得枚举常量的名称 25System.out.println( role1.name() ); // 打印ROLE_ROOT_ADMIN 26System.out.println( role2.name() ); // 打印ROLE_ORDER_ADMIN 27System.out.println( role3.name() ); // 打印ROLE_NORMAL 28 29// valueOf()方法:返回指定名称的枚举常量 30System.out.println( UserRole.valueOf( "ROLE_ROOT_ADMIN" ) ); 31System.out.println( UserRole.valueOf( "ROLE_ORDER_ADMIN" ) ); 32System.out.println( UserRole.valueOf( "ROLE_NORMAL" ) );

switch语句中的Enum

1UserRole userRole = UserRole.ROLE_ORDER_ADMIN; 2switch (userRole) { 3 case ROLE_ROOT_ADMIN: // 枚举变量名称比1,2,3数字更好理解 4 System.out.println("这是系统管理员角色"); 5 break; 6 case ROLE_ORDER_ADMIN: 7 System.out.println("这是订单管理员角色"); 8 break; 9 case ROLE_NORMAL: 10 System.out.println("这是普通用户角色"); 11 break; 12}

3、自定义扩充枚举

扩充UserRole的枚举,加入“角色名——角色编码”的对应关系

1public enum UserRole{ 2 ROLE_ROOT_ADMIN("系统管理员", 000000), 3 ROLE_ORDER_ADMIN("订单管理员", 100000), 4 ROLE_NORMAL("普通用户", 200000), 5 ; 6 7 // 自定义属性 8 private final String roleName; // 角色名称 9 privaye final Integer roleCode; // 角色编码 10 11 // 自定义构造函数 12 UserRole(String roleName, Integer roleCode){ 13 this.roleName = roleName; 14 this.roleCode = roleCode; 15 } 16 17 // 自定义方法 18 public String getRoleName() { 19 return this.roleName; 20 } 21 22 public Integer getRoleCode() { 23 return this.roleCode; 24 } 25 26 public static Integer getRoleCodeByRoleName(String roleName){ 27 for(UserRole enums : UserRole.values()){ 28 if(enums.getRoleName().equals(roleName)){ 29 return enums.getRoleCode(); 30 } 31 } 32 return null; 33 } 34}

从上述代码可知,在enum枚举类中完全可以像在普通Class里一样声明属性、构造函数以及成员方法。

4、枚举+接口的使用

以什么角色能干什么事为例,首先定义一个公用的接口RoleOperation,表示不同角色所能做的操作:

1public interface RoleOperation{ 2 String op(); 3}

定义一个枚举类RoleEnum,依次实现RoleOperation接口:

1public enum RoleEnum implements RoleOperation{ 2 // 系统管理员(有A操作权限) 3 ROLE_ROOT_ADMIN{ 4 @Override 5 public String op() { 6 return"ROLE_ROOT_ADMIN:" + " has AAA permission"; 7 } 8 }, 9 10 // 订单管理员(有B操作权限) 11 ROLE_ORDER_ADMIN { 12 @Override 13 public String op() { 14 return"ROLE_ORDER_ADMIN:" + " has BBB permission"; 15 } 16 }, 17 18 // 普通用户(有C操作权限) 19 ROLE_NORMAL { 20 @Override 21 public String op() { 22 return"ROLE_NORMAL:" + " has CCC permission"; 23 } 24 }; 25}

调用:

1public class JudgeRole{ 2 public String judge(String roleName){ 3 // 一行代码搞定if/else判断不同角色 4 return RoleEnum.valueOf(roleName).op(); 5 } 6}

5、枚举与设计模式

1、单例模式

1public class Singleton{ 2 // 构造函数私有化,避免外部创建实例 3 private Singleton(){ 4 } 5 6 // 定义一个内部枚举 7 public enum SingletonEnum{ 8 9 SEED; // 唯一一个枚举对象,我们称它为“种子选手”! 10 11 private Singleton singleton; 12 13 SingletonEnum(){ 14 singleton = new Singleton(); // 真正创建实例的地方 15 } 16 17 public Singleton getInstance(){ 18 return singleton; 19 } 20 } 21 22 public static Singleton getInstance(){ 23 // 通过枚举的种子选手来获取实例 24 return SingletonEnum.SEED.getInstance; 25 } 26}

2、策略模式 使用枚举写一个基于策略模式的计算器

1public class Test{ 2 3 public enum Calculator{ 4 5 ADDITION{ 6 public Double execute(Double x, Double y){ 7 return x + y; // 加法 8 } 9 }, 10 11 SUBTRACTION { 12 public Double execute( Double x, Double y ) { 13 return x - y; // 减法 14 } 15 }, 16 17 MULTIPLICATION { 18 public Double execute( Double x, Double y ) { 19 return x * y; // 乘法 20 } 21 }, 22 23 24 DIVISION { 25 public Double execute( Double x, Double y ) { 26 return x/y; // 除法 27 } 28 }; 29 30 public abstract Double execute(Double x, Double y); 31 } 32 33 public static void main(String[] args) { 34 System.out.println( Calculator.ADDITION.execute( 4.0, 2.0 ) ); 35 // 打印 6.0 36 System.out.println( Calculator.SUBTRACTION.execute( 4.0, 2.0 ) ); 37 // 打印 2.0 38 System.out.println( Calculator.MULTIPLICATION.execute( 4.0, 2.0 ) ); 39 // 打印 8.0 40 System.out.println( Calculator.DIVISION.execute( 4.0, 2.0 ) ); 41 // 打印 2.0 42 } 43}

6、枚举的集合类

1、EnumSet

1public enum UserRole{ 2 ROLE_ROOT_ADMIN, // 系统管理员 3 4 ROLE_ORDER_ADMIN, // 订单管理员 5 6 ROLE_NORMAL // 普通用户 7}

后台系统新增了一批人,现在需要查看他们是不是某个角色中的一个:

1// 定义管理员角色的专属集合 2EnumSet<UserRole> userRolesForAdmin = EnumSet.of( 3 UserRole.ROLE_ROOT_ADMIN; 4 UserRole.ROLE_ORDER_ADMIN; 5); 6 7// 判断某个进来的用户是否是管理员 8Boolean isAdmin(User user){ 9 if(userRolesForAdmin.contains(user.getRoleName())){ 10 return true; 11 } 12 return false; 13}

2、EnumMap 系统里来了一批人,我们需要统计不同的角色到底有多少人:

1Map<UserRole, Integer> userStatisticMap = new EnumMap<>(UserRole.class); 2for(User user : userList){ 3 Integer num = userStatisticMap.get(user.getUserRole()); 4 if(num != num){ 5 userStatisticMap.put(user.getUserRole(), num + 1); 6 }else{ 7 userStatisticMap.put(user.getUserRole(), 1); 8 } 9}
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )