首页 > 编程语言 >在java中实现两层关联的枚举

在java中实现两层关联的枚举

时间:2023-01-28 11:25:02浏览次数:42  
标签:return PeriodValue 两层 Period periodValue 枚举 java desc

在实际开发中,有各种奇葩的需求,我就遇到一次,在调度任务建依赖的时候,需要选择依赖的周期和周期的值

比如下面这样,如果你依赖天任务,那么还需要选择今天、昨天还是前七天?

周期周期值描述
day today,last7Days,last3Days,last2Days,last1Days 今天、昨天、前两天、前三天、前七天
month thisMonth,lastMonth,lastMonthBegin,lastMonthEnd 本月、上月、上月初、上月末
week thisWeek,lastWeek,lastWednesday 本周、上周、上周一~上周日
hour last3Hours,last24Hours,currentHour,last1Hour 当前小时、前1小时,前2小时,前3小时,前24小时

显而易见,这有两层枚举,关键是怎么实现呢?

枚举类已经有了默认父类,继承是没法考虑了,只能考虑组合

首先定义父类

//日期周期,父枚举
public enum Period {
    DAY("日"),
    MONTH("月"),
    WEEK("周"),
    HOUR("时");

    private String desc;

    Period(String desc) {
        this.desc = desc;
    }

 

然后定义子类

public enum PeriodValue {
    today("今天", Period.DAY),
    last7Days("前7天", Period.DAY),

    thisMonth("本月", Period.MONTH),
    lastMonth("上月", Period.MONTH),

    thisWeek("本周", Period.WEEK),
    lastWeek("上周", Period.WEEK),

    currentHour("当前小时", Period.HOUR),
    last1Hour("前1小时", Period.HOUR);

    private String desc;
    private Period parent;

    PeriodValue(String desc, Period parent) {
        this.desc = desc;
        this.parent = parent;
    }

    public String getDesc() {
        return desc;
    }

    public Period getParent() {
        return parent;
    }

    /**
     * 方法一:在子枚举定义静态方法,根据父枚举,得到子枚举列表
     *
     * @param parent
     * @return
     */
    public static List<PeriodValue> getPeriodValues(Period parent) {
        return Arrays.stream(PeriodValue.values()).filter(periodValue -> {
            return periodValue.getParent().equals(parent);
        }).collect(Collectors.toList());

    }


    public static void main(String[] args) {
        Period day = Period.DAY;
        //方法一
        List<PeriodValue> periodValues = PeriodValue.getPeriodValues(day);
        System.out.println(day);
        System.out.println(periodValues);
      
    }
}

我们在每个子枚举的属性中标记了子枚举对应的父枚举,进而定义了一个静态方法根据父枚举获取子枚举列表

执行下:

DAY
[today, last7Days]

的确建立了父子枚举的关系

但还有另外一种实现方法,就是通过父枚举直接获取子枚举列表

下面是修改后的父枚举实现:

public enum Period {
    DAY("日"){
        @Override
        List<PeriodValue> getChildren() {
            return Arrays.stream(PeriodValue.values()).filter(periodValue -> {
                return periodValue.getParent().equals(this);
            }).collect(Collectors.toList());
        }
    },
    MONTH("月"){
        @Override
        List<PeriodValue> getChildren() {
            return Arrays.stream(PeriodValue.values()).filter(periodValue -> {
                return periodValue.getParent().equals(this);
            }).collect(Collectors.toList());
        }
    },
    WEEK("周"){
        @Override
        List<PeriodValue> getChildren() {
            return Arrays.stream(PeriodValue.values()).filter(periodValue -> {
                return periodValue.getParent().equals(this);
            }).collect(Collectors.toList());
        }
    },
    HOUR("时"){
        @Override
        List<PeriodValue> getChildren() {
            return Arrays.stream(PeriodValue.values()).filter(periodValue -> {
                return periodValue.getParent().equals(this);
            }).collect(Collectors.toList());
        }
    };

    private String desc;

    Period(String desc) {
        this.desc = desc;
    }

    /**
     * 方法二:在父枚举定义抽象类,直接从父枚举获取子枚举列表
     * @return
     */
    abstract List<PeriodValue> getChildren();

此时就可以通过父枚举直接得到子枚举列表,示例如下

public static void main(String[] args) {
        Period day = Period.DAY;
        //方法一
        List<PeriodValue> periodValues = PeriodValue.getPeriodValues(day);
        System.out.println(day);
        System.out.println(periodValues);
        //方法二
        List<PeriodValue> children = day.getChildren();
        System.out.println(children);
    }

结果是一样的,虽然代码有些冗余,但在使用的时候的确是简单了很多,逻辑也更清晰了。

备注:

方法一其实还有另外一个用途,假如子枚举不仅要根据父枚举进行筛选,还有其他筛选条件,类似于有多个父类

此时还可以在子枚举中可以再标记一个属性,再定义一个静态方法进行多条件筛选,非常灵活,而方法二是实现不了这种多条件筛选的。

标签:return,PeriodValue,两层,Period,periodValue,枚举,java,desc
From: https://www.cnblogs.com/wangbin2188/p/17069893.html

相关文章

  • Java Web项目1:水果管理系统
    JavaWeb项目1:水果管理系统核心参考资料:JavaWeb教程笔记尚硅谷JavaWeb教程项目架构体系单一架构技术体系视图(V):用户的操作界面+数据的动态显示前端技术:HTML/CSS/J......
  • 读Java8函数式编程笔记03_高级集合类和收集器
    1. 方法引用1.1. 一种引用方法的轻量级语法1.1.1. 提供了一种简短的语法1.1.2. 标准语法为Classname::methodName1.2. 凡是使用Lambda表达式的地方,就可以使用1.......
  • java多线程基础小白指南--关键字识别(start,run,sleep,wait,join,yield)
    在学习java多线程基础上,会遇到几个关键字,理解并识别它们是掌握多线程的必备知识,下面,我将通过源码或者程序演示给出我对这几个关键字的理解,如果有不同意见,欢迎在评论区或者......
  • java安全-RMI
    Java安全-RMI1、RMI原理浅析RMI(RemoteMethodInvocation)远程方法调用,是允许运行在一个JVM中的对象调用另一个JVM中的对象方法。两台虚拟机可以是同一台宿主机的不......
  • JavaScript学习笔记—正则表达式
    用来定义一个规则通过这个规则计算机可以检查一个字符串是否符合规则或者将字符串中符合规则的内容提取出来也是JS中的一个对象,所以要使用正则表达式,需要先创建正则表达......
  • java学习记录
    makrdown学习标题二级标题字体粗体斜体斜体加粗划线引用引用分割号图片可以用复制的东西超链接点击列表............
  • JavaScript基础知识
    1.编程语言  1.1编程      1.2计算机语言    1.3编程语言    1.4翻译器      1.5编程语言和标记语言的区别   ......
  • Java的基本数据类型
    Java的基本数据类型介绍Java中变量的概念、基本数据类型、基本数据类型变量的使用及它们之间转换,最后还会对基本数据类型与String的转换做一个说明。Author:MsuenbDat......
  • gRPC介绍(以Java为例)
    1.简介1.1gRPC的起源RPC是RemoteProcedureCall的简称,中文叫远程过程调用。用于解决分布式系统中服务之间的调用问题。通俗地讲,就是开发者能够像调用本地方法一样调用......
  • 用 JavaScript 制作一个新年的日历小工具
    2023年,让我们携手一道兔谋大业、做出兔出贡献!同打拼、共丰盈、多喜乐、长安宁,好运一路相随兔气扬眉!......