【工具类】比较优雅的在工具类中,用泛型方法获取枚举的值

2023-11-20

痛点

在代码中,经常用到枚举,也经常用到枚举获取code,获取type,通常我们写的代码如下:

 public  enum Status{
    /**
     *
     */
    YES(1,"是"),
    NO(2,"否")

    ;
    private int code;
    private String msg;

    Status(int code, String msg) {
      this.code = code;
      this.msg = msg;
    }


    public int getCode() {
      return this.code;
    }


    public String getMsg() {
      return this.msg;
    }

    public static Optional<Status> of(int code) {
      for (Status value : values()) {
         if (Objects.equals(value.getCode(),code)){
          return Optional.of(value);
        }
      }
      return Optional.empty();
    }


  }

要根据某个code,得到枚举以及对应的msg,调用of()方法。但是这样的话每个枚举都得写一边,代码行数还不少。不简洁

一开始的优化,就是写了个接口如下:

public interface IEntityEnum {

 public int getCode();

 public String getMsg();

}

然后枚举实现这个接口,相当于一个标准能保证枚举类都能有这样的of方法可以用。但是实际问题还是没解决,代码在每个枚举都要复制。

解决

其实这个也不难想,把这些of方法通通抽取出去在一个工具类中,采用泛型来匹配各种枚举类,但是问题在于,怎么调用values方法呢?怎么告诉编译器我这个方法需要的是一个枚举,我要调用它的values方法,毕竟其他类又没这个静态方法。直到我无意发现了getEnumConstants方法,它是Object类里的。
它的介绍:

an array containing the values comprising the enum class represented by this Class object in the order they’re declared, or null if this Class object does not represent an enum type

一个数组,其中包含组成此 Class 对象表示的枚举类的值,按声明的顺序排列;如果此 Class 对象不表示枚举类型,则为 null

因此工具类就好写了:


import cn.hutool.core.util.StrUtil;
import java.util.Optional;

/**
 * EnumsUtil
 *
 * @author zgd
 * @date 2022/8/9 17:44
 */
public class EnumsUtil {

    public static <T extends IEntityEnum> Optional<T> of(int code, Class<T>  cla) {
        T[] enums = cla.getEnumConstants();
        for (T value : enums) {
            if (code == value.getCode()){
                return Optional.of(value);
            }
        }
        return Optional.empty();
    }



    public static <T extends IEntityEnum> String ofMsg(int code, Class<T>  cla) {
        Optional<T> of = of(code,cla);
        return of.isPresent() ? of.get().getMsg() : "";
    }

    public static <T extends IEntityEnum> Integer ofCode(String msg, Class<T>  cla) {
        if (StrUtil.isEmpty(msg)){
            return null;
        }
        T[] enums = cla.getEnumConstants();
        for (T value : enums) {
            if (msg.equals(value.getMsg())){
                return value.getCode();
            }
        }
        return null;
    }
/**
* 可以试下效果
*/
    public static void main(String[] args) {
        System.out.println(EnumsUtil.ofMsg(1, SourceEnum.class));
        System.out.println(EnumsUtil.ofMsg(2, SourceEnum.class));
    }
}


优化更灵活的泛型

用了一天后发现一个问题, 接口IEntityEnum写死了int code和String msg, 那如果有时候code我们需要String类型,这个场景也很常见.
因此再往上包装一层

  • 增加一个接口

/**
 * IEnum
 *
 * @author zgd
 * @date 2022/8/10 18:09
 */
public interface IEnum<T,E> {

    public T getCode();

    public E getMsg();

}

  • 继承这个接口,这个用的比较多,作为一个默认的子接口
public interface IEntityEnum extends IEnum<Integer,String> {

 public Integer getCode();

 public String getMsg();

}


import cn.hutool.core.util.StrUtil;

import java.util.Optional;

/**
 * EnumsUtil
 *
 * @author zgd
 * @date 2022/8/9 17:44
 */
public class EnumsUtil {

    public static  <E,V,T extends IEnum<E,V>>  Optional<T> of(E code, Class<T>  cla) {
        T[] enums = cla.getEnumConstants();
        for (T value : enums) {
            if (code == value.getCode()){
                return Optional.of(value);
            }
        }
        return Optional.empty();
    }



    public static <E,V,T extends IEnum<E,V>> V ofMsg(E code, Class<T>  cla) {
        Optional<T> of = of(code,cla);
        return of.map(IEnum::getMsg).orElse(null);
    }

    public static <E,V,T extends IEnum<E,V>> E ofCode(String msg, Class<T>  cla) {
        if (StrUtil.isEmpty(msg)){
            return null;
        }
        T[] enums = cla.getEnumConstants();
        for (T value : enums) {
            if (msg.equals(value.getMsg())){
                return value.getCode();
            }
        }
        return null;
    }

    public static void main(String[] args) {
        System.out.println(EnumsUtil.ofMsg("YES", TypeEnum.class));
    }
}
  • 如果我们需要一个code是String类型的,不实现IEntityEnum,直接实现它的父接口
  /**
     * TypeEnum
     *
     * @author zgd
     * @date 2022/8/10 18:41
     */
    public enum TypeEnum implements IEnum<String,String> {

        /**
         *
        */
        YES("YES","是"),
        NO("NO","否"),

        ;

        private String code;
        private String msg;

        TypeEnum(String code, String msg) {
            this.code = code;
            this.msg = msg;
        }

        @Override
        public String getCode() {
            return this.code;
        }

        @Override
        public String getMsg() {
            return this.msg;
        }
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【工具类】比较优雅的在工具类中,用泛型方法获取枚举的值 的相关文章

  • Java 中等效的并行扩展

    我在 Net 开发中使用并行扩展有一些经验 但我正在考虑在 Java 中做一些工作 这些工作将受益于易于使用的并行库 JVM 是否提供任何与并行扩展类似的工具 您应该熟悉java util concurrent http java sun
  • 如何默认将 Maven 插件附加到阶段?

    我有一个 Maven 插件应该在编译阶段运行 所以在项目中consumes我的插件 我必须做这样的事情
  • 使用 Android 发送 HTTP Post 请求

    我一直在尝试从 SO 和其他网站上的大量示例中学习 但我无法弄清楚为什么我编写的示例不起作用 我正在构建一个小型概念验证应用程序 它可以识别语音并将其 文本 作为 POST 请求发送到 node js 服务器 我已确认语音识别有效 并且服务
  • 在 HTTPResponse Android 中跟踪重定向

    我需要遵循 HTTPost 给我的重定向 当我发出 HTTP post 并尝试读取响应时 我得到重定向页面 html 我怎样才能解决这个问题 代码 public void parseDoc final HttpParams params n
  • 制作一个交互式Windows服务

    我希望我的 Java 应用程序成为交互式 Windows 服务 用户登录时具有 GUI 的 Windows 服务 我搜索了这个 我发现这样做的方法是有两个程序 第一个是服务 第二个是 GUI 程序并使它们进行通信 服务将从 GUI 程序获取
  • Final字段的线程安全

    假设我有一个 JavaBeanUser这是从另一个线程更新的 如下所示 public class A private final User user public A User user this user user public void
  • 列出jshell中所有活动的方法

    是否有任何命令可以打印当前 jshell 会话中所有新创建的方法 类似的东西 list但仅适用于方法 您正在寻找命令 methods all 它会打印所有方法 包括启动 JShell 时添加的方法 以及失败 被覆盖或删除的方法 对于您声明的
  • JavaMail 只获取新邮件

    我想知道是否有一种方法可以在javamail中只获取新消息 例如 在初始加载时 获取收件箱中的所有消息并存储它们 然后 每当应用程序再次加载时 仅获取新消息 而不是再次重新加载它们 javamail 可以做到这一点吗 它是如何工作的 一些背
  • Spring Data JPA 应用排序、分页以及 where 子句

    我目前正在使用 Spring JPA 并利用此处所述的排序和分页 如何通过Spring data JPA通过排序和可分页查询数据 https stackoverflow com questions 10527124 how to query
  • 无法解析插件 Java Spring

    我正在使用 IntelliJ IDEA 并且我尝试通过 maven 安装依赖项 但它给了我这些错误 Cannot resolve plugin org apache maven plugins maven clean plugin 3 0
  • 斯坦福 NLP - 处理文件列表时 OpenIE 内存不足

    我正在尝试使用斯坦福 CoreNLP 中的 OpenIE 工具从多个文件中提取信息 当多个文件 而不是一个 传递到输入时 它会给出内存不足错误 All files have been queued awaiting termination
  • 十进制到八进制的转换[重复]

    这个问题在这里已经有答案了 可能的重复 十进制转换错误 https stackoverflow com questions 13142977 decimal conversion error 我正在为一个类编写一个程序 并且在计算如何将八进
  • Java TestNG 与跨多个测试的数据驱动测试

    我正在电子商务平台中测试一系列商店 每个商店都有一系列属性 我正在考虑对其进行自动化测试 是否有可能有一个数据提供者在整个测试套件中提供数据 而不仅仅是 TestNG 中的测试 我尝试不使用 testNG xml 文件作为机制 因为这些属性
  • 如何将 pfx 文件转换为 jks,然后通过使用 wsdl 生成的类来使用它来签署传出的肥皂请求

    我正在寻找一个代码示例 该示例演示如何使用 PFX 证书通过 SSL 访问安全 Web 服务 我有证书及其密码 我首先使用下面提到的命令创建一个 KeyStore 实例 keytool importkeystore destkeystore
  • 为什么HashMap不能保证map的顺序随着时间的推移保持不变

    我在这里阅读有关 Hashmap 和 Hashtable 之间的区别 http javarevisited blogspot sg 2010 10 difference Between hashmap and html http javar
  • 如何在控制器、服务和存储库模式中使用 DTO

    我正在遵循控制器 服务和存储库模式 我只是想知道 DTO 在哪里出现 控制器应该只接收 DTO 吗 我的理解是您不希望外界了解底层域模型 从领域模型到 DTO 的转换应该发生在控制器层还是服务层 在今天使用 Spring MVC 和交互式
  • Java列表的线程安全

    我有一个列表 它将在线程安全上下文或非线程安全上下文中使用 究竟会是哪一个 无法提前确定 在这种特殊情况下 每当列表进入非线程安全上下文时 我都会使用它来包装它 Collections synchronizedList 但如果不进入非线程安
  • 编译器抱怨“缺少返回语句”,即使不可能达到缺少返回语句的条件

    在下面的方法中 编译器抱怨缺少退货声明即使该方法只有一条路径 并且它包含一个return陈述 抑制错误需要另一个return陈述 public int foo if true return 5 鉴于Java编译器可以识别无限循环 https
  • 当我从 Netbeans 创建 Derby 数据库时,它存储在哪里?

    当我从 netbeans 创建 Derby 数据库时 它存储在哪里 如何将它与项目的其余部分合并到一个文件夹中 右键单击Databases gt JavaDB in the Service查看并选择Properties This will
  • 如何实现仅当可用内存较低时才将数据交换到磁盘的写缓存

    我想将应用程序生成的数据缓存在内存中 但如果内存变得稀缺 我想将数据交换到磁盘 理想情况下 我希望虚拟机通知它需要内存并将我的数据写入磁盘并以这种方式释放一些内存 但我没有看到任何方法以通知我的方式将自己挂接到虚拟机中before an O

随机推荐

  • Maven创建现实公司应用web项目

    1 步骤说明 STEP BY STEP 见 下载地址 http download csdn net detail jun55xiu 8314633 2 过程出现的问题汇总 1 Failed to execute goalorg apache
  • css图片不断放大缩小的动画效果

    img class move img width 26px src assets img btn coupon 2x png alt move img animation name scaleDraw 关键帧名称 animation tim
  • 前端面试中级开发必须知道跨域解决方案

    跨域 不同协议 不同URL 不同端口号都会产生跨域 解决跨域的方案 postMessage web worker iframe Jsonp 用script标签请求地址 标签可以跨域 cors 服务端设置响应头信息 允许跨域 1 最常见用co
  • 【Java进阶营】29个你必须学会的微服务面试问题(含答案解析)

    这29个微服务面试题基本涵盖了方方面 希望对你有所帮助 外链图片转存失败 源站可能有防盗链机制 建议将图片保存下来直接上传 img YvPsK1zg 1651230439289 https upload images jianshu io
  • Starting udev卡死的问题

    Linux启动停止在Starting udev 一 出现问题 在VM的CentOS 5 4 32bit上重新编译了内核 2 6 19 7 启动新内核时 停在starting udev 然后按下Ctrl C取消 才能继续启动 于是google
  • 解决View drawableLeft左侧图片大小不可控的问题

    今天在制作带文字的图片按钮的时候 使用了TextView的drawableLeft属性 但是在使用的过程中 我发现我所使用的图片资源的大小过大 导致整个效果很不和谐 可是drawableLeft并不能在xml通过属性控制它的大小 这时 我就
  • 《OpenGL编程指南》示例笔记(2)--独立地移动光源

    TITLE OpenGL编程指南 示例笔记 2 独立地移动光源 AUTHOR norains DATE Monday 21 June 2010 Environment Windows XP 示例概述 例名 独立地移动光源 序号 5 6 页码
  • TVS管电路原理图符号及选型举例

    TVS管的电路原理图符号与稳压二极管符号类似 结构也都差不多 了解TVS管的电路原理图符号是掌握TVS管符合选型的基础 一般常见的TVS管电路原理图符号有 VBR IPP IR VRWM VC PM CP VBR代表的是 击穿电压 IPP代
  • 最详细的Vue实现日历组件Calendar(日期点击多选,滑动多选)

    1 成果演示 1 1 日期的切换 1 2 点击多选 1 3 滑动多选 2 实现基本的日期渲染 2 1 思路 2 1 1 要用到的Date对象方法 new Date 2020 4 1 getDay 计算传入的日期是星期几 返回值0表示星期天
  • 官网下载Eclipse

    1 打开Eclipse官网 https www eclipse org 也可以在百度中 搜索 Eclipse 2 点击 Download 3 点击 Download Pakeges 4 下拉 选择所要的版本和系统 5 点击 Select A
  • OJ-合并两个有序链表

    题目描述 代码如下 Definition for singly linked list struct ListNode int val struct ListNode next struct ListNode mergeTwoLists s
  • C# 中Object的方法含义以及使用(详)

    如下图是object中的方法 上图来源于我阅读C 入门经典第8版的书本当中 图中明确标明方法的使用 以及含义 Equals方法 比较两个对象是否相等 在Object是所有的父类大家都知道 其中Object中方法Equals 有两种 obje
  • 【兄弟反目成仇系列】:我只是写了一个爆炸信息窗口脚本,好兄弟追了我几条街~

    文章目录 真的来咯 爆炸信息窗口 设计思路 模块准备 删除好友警告 源代码 这时你可能会问 批量获取表情包 结束语 专栏 Python零基础入门篇 Python网络蜘蛛 Python数据分析 Django基础入门宝典 小玩意儿 Web前端学
  • c#方法参数:in

    方法参数in只能读入 不能在方法内修改 它和ref一样也需要在作为实参时就已经进行了初始化 而且同ref一样 无论定义方法还是调用方法都需要加上in关键字 class Program static void Add in int num1
  • 等级测评——定级、等级划分及测评时间

    定级 在等级保护中 定级这个步骤很关键 首先我们需要知道我们这个资产是什么样的一个级别 一级二级三级 因为不同的级别表示着我们要对这个资产做相应的保护 那么我们这个定级是怎么么定级呢 参考的又是什么标准呢 首先我们需要先确认定级对象 这个对
  • R----stringr包介绍学习

    1 stringr介绍 stringr包被定义为一致的 简单易用的字符串工具集 所有的函数和参数定义都具有一致性 比如 用相同的方法进行NA处理和0长度的向量处理 字符串处理虽然不是R语言中最主要的功能 却也是必不可少的 数据清洗 可视化等
  • Verilog中$timeformat的用法

    Verilog中 timeformat的用法 更新历史 20200807 首次发布 语法 timeformat的语法如下 timeformat units number precision number suffix string mini
  • (转发)西门子S7-1200PLC之间TCP通信实例步骤

    1 软件组态 新建两个CPU 在组态界面的网络视图手绘连接两个PLC的以太网口 如下 2 在两个CPU以太网口的属性中设置IP地址 设置同一网段 方便调试 3 在PLC 1程序块中添加个背景数据块 新建接收数组跟发送数组 以方便存放接收或发
  • mysql本机地址_mysql连接时用的IP地址是不是电脑本机上的IP地址呢!

    展开全部 是root用户的话 IP就是或 lt 127 0 0 1 gt 只是代表使用本机 不是代表本机IP地址 操作方法如下62616964757a686964616fe58685e5aeb931333433623737 1 首先 利用N
  • 【工具类】比较优雅的在工具类中,用泛型方法获取枚举的值

    目录 痛点 解决 优化更灵活的泛型 痛点 在代码中 经常用到枚举 也经常用到枚举获取code 获取type 通常我们写的代码如下 public enum Status YES 1 是 NO 2 否 private int code priv