枚举Enum的使用

qchen 等级 274 0 1
标签: enum枚举类型

1、为什么使用枚举?

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

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

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

public void judgeBlogStatus(int status){
    ...
}

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

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

2、如何使用Enum

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

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

枚举的基本用法:

UserRole role1 = UserRole.ROLE_ROOT_ADMIN;
UserRole role2 = UserRole.ROLE_ORDER_ADMIN;
UserRole role3 = UserRole.ROLE_NORMAL;

// values()方法:返回所有枚举常量的数组集合
for(UserRole role : UserRole.values()){
    System.out.println(role);
}
// 打印:
// ROLE_ROOT_ADMIN
// ROLE_ORDER_ADMIN
// ROLE_NORMAL

// ordinal()方法:返回枚举常量的序数,注意从0开始
System.out.println( role1.ordinal() ); // 打印0
System.out.println( role2.ordinal() ); // 打印1
System.out.println( role3.ordinal() ); // 打印2

// compareTo()方法:枚举常量间的比较
System.out.println( role1.compareTo(role2) ); //打印-1
System.out.println( role2.compareTo(role3) ); //打印-2
System.out.println( role1.compareTo(role3) ); //打印-2

// name()方法:获得枚举常量的名称
System.out.println( role1.name() ); // 打印ROLE_ROOT_ADMIN
System.out.println( role2.name() ); // 打印ROLE_ORDER_ADMIN
System.out.println( role3.name() ); // 打印ROLE_NORMAL

// valueOf()方法:返回指定名称的枚举常量
System.out.println( UserRole.valueOf( "ROLE_ROOT_ADMIN" ) );
System.out.println( UserRole.valueOf( "ROLE_ORDER_ADMIN" ) );
System.out.println( UserRole.valueOf( "ROLE_NORMAL" ) );

switch语句中的Enum

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

3、自定义扩充枚举

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

public enum UserRole{
    ROLE_ROOT_ADMIN("系统管理员", 000000),
    ROLE_ORDER_ADMIN("订单管理员", 100000),
    ROLE_NORMAL("普通用户", 200000),
    ;

    // 自定义属性
    private final String roleName; // 角色名称
    privaye final Integer roleCode; // 角色编码

    // 自定义构造函数
    UserRole(String roleName, Integer roleCode){
        this.roleName = roleName;
        this.roleCode = roleCode;
    }

    // 自定义方法
    public String getRoleName() {
        return this.roleName;
    }

    public Integer getRoleCode() {
        return this.roleCode;
    }

    public static Integer getRoleCodeByRoleName(String roleName){
        for(UserRole enums : UserRole.values()){
            if(enums.getRoleName().equals(roleName)){
                return enums.getRoleCode();
            }
        }
        return null;
    }
}

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

4、枚举+接口的使用

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

public interface RoleOperation{
    String op();
}

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

public enum RoleEnum implements RoleOperation{
    // 系统管理员(有A操作权限)
    ROLE_ROOT_ADMIN{
        @Override
        public String op() {
            return"ROLE_ROOT_ADMIN:" + " has AAA permission";
        }
    },

    // 订单管理员(有B操作权限)
    ROLE_ORDER_ADMIN {
        @Override
        public String op() {
            return"ROLE_ORDER_ADMIN:" + " has BBB permission";
        }
    },

    // 普通用户(有C操作权限)
    ROLE_NORMAL {
        @Override
        public String op() {
            return"ROLE_NORMAL:" + " has CCC permission";
        }
    };
}

调用:

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

5、枚举与设计模式

1、单例模式

public class Singleton{
    // 构造函数私有化,避免外部创建实例
    private Singleton(){
    }

    // 定义一个内部枚举
    public enum SingletonEnum{

        SEED; // 唯一一个枚举对象,我们称它为“种子选手”!

        private Singleton singleton;

        SingletonEnum(){
            singleton = new Singleton();  // 真正创建实例的地方
        }

        public Singleton getInstance(){
            return singleton;
        }
    }

    public static Singleton getInstance(){
        // 通过枚举的种子选手来获取实例
        return SingletonEnum.SEED.getInstance;
    }
}

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

public class Test{

    public enum Calculator{

        ADDITION{
            public Double execute(Double x, Double y){
                return x + y; // 加法
            }
        },

        SUBTRACTION {
            public Double execute( Double x, Double y ) {
                return x - y; // 减法
            }
        },

        MULTIPLICATION {
            public Double execute( Double x, Double y ) {
                return x * y; // 乘法
            }
        },


        DIVISION {
            public Double execute( Double x, Double y ) {
                return x/y;  // 除法
            }
        };

        public abstract Double execute(Double x, Double y);
    }

    public static void main(String[] args) {
        System.out.println( Calculator.ADDITION.execute( 4.0, 2.0 ) );
        // 打印 6.0
        System.out.println( Calculator.SUBTRACTION.execute( 4.0, 2.0 ) );
        // 打印 2.0
        System.out.println( Calculator.MULTIPLICATION.execute( 4.0, 2.0 ) );
        // 打印 8.0
        System.out.println( Calculator.DIVISION.execute( 4.0, 2.0 ) );
        // 打印 2.0
    }
}

6、枚举的集合类

1、EnumSet

public enum UserRole{
    ROLE_ROOT_ADMIN,  // 系统管理员

    ROLE_ORDER_ADMIN, // 订单管理员

    ROLE_NORMAL       // 普通用户
}

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

// 定义管理员角色的专属集合
EnumSet<UserRole> userRolesForAdmin = EnumSet.of(
    UserRole.ROLE_ROOT_ADMIN;
    UserRole.ROLE_ORDER_ADMIN;
);

// 判断某个进来的用户是否是管理员
Boolean isAdmin(User user){
    if(userRolesForAdmin.contains(user.getRoleName())){
        return true;
    }
    return false;
}

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

Map<UserRole, Integer> userStatisticMap = new EnumMap<>(UserRole.class);
for(User user : userList){
    Integer num = userStatisticMap.get(user.getUserRole());
    if(num != num){
        userStatisticMap.put(user.getUserRole(), num + 1);
    }else{
        userStatisticMap.put(user.getUserRole(), 1);
    }
}
收藏
评论区

相关推荐

Java枚举类妙用
上代码:java@Getterpublic enum NodeIdStatusRef { / reference / NI001_A001_AGREE(NodeIdEnum.NI001.getNodeId(), OrderStatus.A101.getCode(), OrderStatus.A101.getCo
JAVA 高级特性枚举和泛型
 枚举:  ===== 语法:  public enum 枚举名 { 枚举值表(罗列所有值) }  例如:  public enum EnumTest{MON,TUE,WED.THU,FRI,SAT,SUN} 枚举操作 ---取值 1. 使用“枚举.variable“的形式取出枚举中的指定内容   EnumTest e = Eunm
JDK 的这3个bug,你发现了吗?
![](https://oscimg.oschina.net/oscnet/1de097fb-b6d0-4eee-9bf5-905adb265b6d.jpg) > 作者:孤独的探索号 > > 来源:my.oschina.net/tommylemon/blog/2967187 **1.Annotation引用非空enum数组返回空数组** 首
JDK的3个bug
**1.Annotation引用非空enum数组返回空数组** 首次发现时的环境:JDK 1.8 首次发现所在项目:[APIJSON](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fgithub.com%2FTommyLemon%2FAPIJSON) 测试用例: publi
Java分享笔记:自定义枚举类 & 使用enum关键字定义枚举类
  在JDK1.5之前没有enum关键字,如果想使用枚举类,程序员需要根据Java语言的规则自行设计。从JDK1.5开始,Java语言添加了enum关键字,可以通过该关键字方便地定义枚举类。这种枚举类有自己的程序编写规则,并且具有一些特殊方法。   下面是笔者分别针对自定义枚举类和enum枚举类的程序设计。 **\[1\]** 自定义枚举类
Java日期时间API系列22
  Java8中为月份和星期新增的了,Month和DayOfWeek,来处理月份和星期的特殊问题,这2个类都是枚举类,对Month、DayOfWeek源码说明和简单应用,月份英文,月份英文简称,月份中文,星期英文,星期英文简称,星期中文等。 1.Month ------- ### 1.1 部分源码: \* @implSpec \* This is an
Java枚举使用场景
用法一:常量 ------ Java代码  1 public enum Color { 2 RED, GREEN, BLANK, YELLOW 3 } 用法二:switch ---------- JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。 Java
Java枚举使用详解
package com.ljq.test; /**  * 枚举用法详解  *   *   */ public class TestEnum {     /**      * 普通枚举      *       */     public enum Col
Java枚举的小知识点
enum 是jdk1.5引入的,使用它可以创建枚举类型,就像使用class创建类一样。 enum关键字创建的枚举类型默认是java.lang.Enum(一个抽象类)的子类 用法1 常量 ====== 一般定义常量都是 public static final …,现在可以把相关常量都放在一个枚举类里,而且枚举比常量提供更多方法 1. enum sea
Java枚举类使用
用法一:常量 ------ 在JDK1.5 之前,我们定义常量都是: public static fianl.... 。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。  public enum Color { RED, GREEN, BLANK, YELLOW } 用法二
java枚举
https://www.cnblogs.com/hyl8218/p/5088287.html 摘抄并自查 **语法(定义)** 创建枚举类型要使用 enum 关键字,隐含了所创建的类型都是 java.lang.Enum 类的子类。枚举类符合通用模式 Class Enum<E extends Enum<E>>,而 E 表示枚举类型的名称。枚举类型的每一
java枚举类型
java枚举类型enum 枚举类型是java 5新增特性的一部分,是一种特殊的数据类型(既是一种类类型但是又比类类型多些特殊的约束) 枚举定义的方式: public enum Day{ MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY } 定义
java枚举类型enum的使用
**java** **枚举类型enum 的使用** 最近跟同事讨论问题的时候,突然同事提到我们为什么java 中定义的常量值不采用enmu 枚举类型,而采用public final static  类型来定义呢?以前我们都是采用这种方式定义的,很少采用enum 定义,所以也都没有注意过,面对突入起来的问题,还真有点不太清楚为什么有这样的定义。既然不明白就抽
Linux epoll版定时器
#ifndef __MYTIMER_H_ #define __MYTIMER_H_ /*************** 高并发场景下的定时器 *****************/ //定时器回调函数 typedef void *(*TimerCallback)(int fd, void
枚举Enum的使用
1、为什么使用枚举?以博客网站为例,文章有三种状态:草稿、审核和发布,可将其定义为静态常量:javapublic class BlogStatus public static final int Draft 1; // 草稿 public static final int Review 2; // 审核 public static fi

热门文章

Java中6种创建对象的方式如何正确使用float和double?Java8函数式编程

最新文章

Java8函数式编程Java中6种创建对象的方式如何正确使用float和double?