1.定义主对象

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.List;@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ApiModel("定时任务corn对象")
public class TimingCornVo {@ApiModelProperty(value = "corn字符串")String corn;@ApiModelProperty(value = "corn转换后数据集合")List<TimingCornSubVo> subVoList;
}

2.定义子对象,用于存放corn的每个部分数据

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.ArrayUtils;@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ApiModel("定时任务corn子对象")
public class TimingCornSubVo {@ApiModelProperty(value = "数据类型[0:秒,1:分,2时,3:日,4:月,5:周,6:年]")Integer type;@ApiModelProperty(value = "使用类型[0:不指定,1:每单位执行,2:周期执行内单位频率执行,3:指定开始时间和频率,4:指定时间执行,5最后一个(日和周,月中最后一个月或月中最后的星期)]")Integer useType;@ApiModelProperty(value = "执行时间数据[useType2:两个数据,表示x-y,useType3:任意个合法范围内数值],useType4:两个数据,表示x/y")Integer[] data;/*** 参数校验* 在工具类中对顺序进行了排序,因此此处不校验大小问题*/public void checkParam() throws Exception {if (null==type||type<0||type>6){throw new Exception("类型取值不合法");}if (null==useType||useType<0||useType>5){throw new Exception("使用类型取值不合法");}if (useType == 0){if (type<3){throw new Exception("秒,分,时使用类型不能为不指定");}}else if (useType == 2){if (ArrayUtils.isEmpty(data)||data.length!=2){throw new Exception("周期执行类型数据必须为两个");}}else if (useType == 3){if (ArrayUtils.isEmpty(data)||data.length!=2){throw new Exception("指定开始和频率类型数据必须为两个");}}else if (useType == 4){if (ArrayUtils.isEmpty(data)&&type!=6){throw new Exception("指定时间类型数据不能为空");}for (Integer datum : data) {switch (type){case 0:if (datum<0||datum>59){throw new Exception("秒只能为1-60");}break;case 1:if (datum<0||datum>59){throw new Exception("分只能为1-60");}break;case 2:if (datum<0||datum>23){throw new Exception("时只能为1-24");}break;case 3:if (datum<1||datum>31){throw new Exception("日只能为1-31");}break;case 4:if (datum<1||datum>12){throw new Exception("月只能为1-12");}break;case 5:if (datum<1||datum>7){throw new Exception("周只能为1-7");}break;case 6:if (datum<1970||datum>2099){throw new Exception("年只能为1970-2099");}break;}}}else if (useType == 4){if (type!=3||type!=5){throw new Exception("最后一个使用类型仅日和周可以使用");}else if (type==5){if (ArrayUtils.isEmpty(data)||data.length!=1){throw new Exception("最后一个使用类型必须指定一个星期数值");}}}}}

3.创建对象和corn字符串转换工具类

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;import java.util.*;
import java.util.regex.Pattern;/*** corn转换工具类*/
public class TimingCornUtil {//corn正则校验private static final String regEx = "^\\s*($|#|\\w+\\s*=|(\\?|\\*|(?:[0-5]?\\d)(?:(?:-|\\/|\\,)(?:[0-5]?\\d))?(?:,(?:[0-5]?\\d)(?:(?:-|\\/|\\,)(?:[0-5]?\\d))?)*)\\s+(\\?|\\*|(?:[0-5]?\\d)(?:(?:-|\\/|\\,)(?:[0-5]?\\d))?(?:,(?:[0-5]?\\d)(?:(?:-|\\/|\\,)(?:[0-5]?\\d))?)*)\\s+(\\?|\\*|(?:[01]?\\d|2[0-3])(?:(?:-|\\/|\\,)(?:[01]?\\d|2[0-3]))?(?:,(?:[01]?\\d|2[0-3])(?:(?:-|\\/|\\,)(?:[01]?\\d|2[0-3]))?)*)\\s+(\\?|\\*|(?:0?[1-9]|[12]\\d|3[01])(?:(?:-|\\/|\\,)(?:0?[1-9]|[12]\\d|3[01]))?(?:,(?:0?[1-9]|[12]\\d|3[01])(?:(?:-|\\/|\\,)(?:0?[1-9]|[12]\\d|3[01]))?)*)\\s+(\\?|\\*|(?:[1-9]|1[012])(?:(?:-|\\/|\\,)(?:[1-9]|1[012]))?(?:L|W)?(?:,(?:[1-9]|1[012])(?:(?:-|\\/|\\,)(?:[1-9]|1[012]))?(?:L|W)?)*|\\?|\\*|(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(?:(?:-)(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?(?:,(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(?:(?:-)(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?)*)\\s+(\\?|\\*|(?:[0-6])(?:(?:-|\\/|\\,|#)(?:[0-6]))?(?:L)?(?:,(?:[0-6])(?:(?:-|\\/|\\,|#)(?:[0-6]))?(?:L)?)*|\\?|\\*|(?:MON|TUE|WED|THU|FRI|SAT|SUN)(?:(?:-)(?:MON|TUE|WED|THU|FRI|SAT|SUN))?(?:,(?:MON|TUE|WED|THU|FRI|SAT|SUN)(?:(?:-)(?:MON|TUE|WED|THU|FRI|SAT|SUN))?)*)(|\\s)+(\\?|\\*|(?:|\\d{4})(?:(?:-|\\/|\\,)(?:|\\d{4}))?(?:,(?:|\\d{4})(?:(?:-|\\/|\\,)(?:|\\d{4}))?)*))$";private static final Pattern cornPattern = Pattern.compile(regEx);/*** obj转corn字符串* @param cornVo* @return* @throws Exception*/public static String objToStr(TimingCornVo cornVo) throws Exception {List<TimingCornSubVo> subVoList = cornVo.getSubVoList();//年数据可以没有,因此子数据集合为6-7个if (CollectionUtils.isEmpty(subVoList)||subVoList.size()<6||subVoList.size()>7){throw new Exception("数据错误");}//对数据按照日期类型排序subVoList.sort(Comparator.comparing(TimingCornSubVo::getType));//使用空格对字符串进行拼接StringJoiner cornStrJoiner = new StringJoiner(" ");for (int i = 0; i < subVoList.size(); i++) {TimingCornSubVo subVo = subVoList.get(i);//校验参数subVo.checkParam();Integer[] data = subVo.getData();if (subVo.getType()!=i){throw new Exception("数据日期类型错误,必须含有秒,分,时,日,月,周这6种数据");}if (ArrayUtils.isNotEmpty(data)){//对数据进行排序,防止出现填反的情况Arrays.sort(data);}//i-type-0:秒,1:分,2时,3:日,4:月,5:周,6:年//useType0:不指定,1:每单位执行,2:周期执行内单位频率执行,3:指定开始时间和频率,4:指定时间执行,5最后一个switch (subVo.getUseType()){case 0:cornStrJoiner.add("?");break;case 1:cornStrJoiner.add("*");break;case 2:cornStrJoiner.add(data[0]+"-"+data[1]);break;case 3:cornStrJoiner.add(data[0]+"/"+data[1]);break;case 4:StringJoiner dataJoiner = new StringJoiner(",");for (Integer datum : data) {dataJoiner.add(datum+"");}cornStrJoiner.add(dataJoiner.toString());break;case 5:if (i==3){cornStrJoiner.add("L");}else {cornStrJoiner.add(data[0]+"L");}break;}}cornVo.setCorn(cornStrJoiner.toString());return cornStrJoiner.toString();}/*** corn字符串转obj* @param corn* @return*/public static TimingCornVo strToObj(String corn) throws Exception {if (StringUtils.isEmpty(corn)){throw new Exception("corn表达式为空");}if (!cornPattern.matcher(corn).matches()){throw new Exception("corn表达式格式有误");}String[] data = corn.split(" ");List<TimingCornSubVo> subVoList = new ArrayList<>();TimingCornVo result = TimingCornVo.builder().corn(corn).subVoList(subVoList).build();for (int i = 0; i < data.length; i++) {TimingCornSubVo subVo = TimingCornSubVo.builder().type(i).build();String subStr = data[i];//useType0:不指定,1:每单位执行,2:周期执行内单位频率执行,3:指定开始时间和频率,4:指定时间执行,5最后一个if ("?".equals(subStr)){subVo.setUseType(0);}else if ("*".equals(subStr)){subVo.setUseType(1);}else if (subStr.contains("-")){subVo.setUseType(2);String[] split = subStr.split("-");Integer[] subStrSplitData = new Integer[2];subStrSplitData[0] = Integer.parseInt(split[0]);subStrSplitData[1] = Integer.parseInt(split[1]);subVo.setData(subStrSplitData);}else if (subStr.contains("/")){subVo.setUseType(3);String[] split = subStr.split("/");Integer[] subStrSplitData = new Integer[2];subStrSplitData[0] = Integer.parseInt(split[0]);subStrSplitData[1] = Integer.parseInt(split[1]);subVo.setData(subStrSplitData);}else if (subStr.contains("L")){subVo.setUseType(5);if (i==5){Integer[] subStrSplitData = new Integer[1];subStrSplitData[0] = Integer.parseInt(subStr.replace("L",""));subVo.setData(subStrSplitData);}}else{subVo.setUseType(4);String[] split = subStr.split(",");Integer[] subStrSplitData = new Integer[split.length];for (int i1 = 0; i1 < subStrSplitData.length; i1++) {subStrSplitData[i1] = Integer.parseInt(split[i1]);}subVo.setData(subStrSplitData);}subVoList.add(subVo);}return result;}
}

4.测试

    public static void main(String[] args) throws Exception {String corn = "0 15,17,19 10/5 ? * 6L 2002-2005";TimingCornVo timingCornVo = TimingCornUtil.strToObj(corn);for (TimingCornSubVo subVo : timingCornVo.getSubVoList()) {System.out.println(subVo.getType()+"|"+subVo.getUseType()+"|"+ArrayUtils.toString(subVo.getData()));}System.out.println(corn);System.out.println(TimingCornUtil.objToStr(timingCornVo));//测试结果可以看出corn字符串转换对象符合预期并且可以正确转回corn字符串}

JAVA 定时任务Corn的对象设计和corn字符串转换相关推荐

  1. java中如何输入一个字符(用字符串转换)

    java中的Scanner类中并没有包括单独输入char型字符的情况,但是我们可以通过输入一个长度仅为1的字符串,然后将字符串转换为char型字符,再用新的char型变量接收就好了. java源文件名 ...

  2. java定时任务框架elasticjob详解

    这篇文章主要介绍了java定时任务框架elasticjob详解,Elastic-Job是ddframe中dd-job的作业模块中分离出来的分布式弹性作业框架.该项目基于成熟的开源产品Quartz和Zo ...

  3. Java定时任务技术分析

    <从零打造项目>系列文章 工具 比MyBatis Generator更强大的代码生成器 ORM框架选型 SpringBoot项目基础设施搭建 SpringBoot集成Mybatis项目实操 ...

  4. java初始化实例化_Java对象的创建过程:类的初始化与实例化

    一.Java对象创建时机 我们知道,一个对象在可以被使用之前必须要被正确地实例化.在Java代码中,有很多行为可以引起对象的创建,最为直观的一种就是使用new关键字来调用一个类的构造函数显式地创建对象 ...

  5. java在何时获得对象的确切类型_JAVA面试题(1)

    基础部分 面向对象 1.谈谈你对多态的理解. 答:在java中对于多态的理解是很重要的 多态的定义: 允许不同类的对象对同一消息做出相应,同一消息可以根据发送对象的不同而采用多种不同的行为方式,(发送 ...

  6. Java深入了解String对象

    一,从根本上认识java.lang.String类和String池 首先,我建议先看看String类的源码实现,这是从本质上认识String类的根本出发点.从中可以看到: 1,String类是fina ...

  7. Week04-面向对象设计与继承

    Week04-面向对象设计与继承 1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 重载 static 静态 final 继承和多态 类型判定与类型转换 抽象类 1.2 尝试使用 ...

  8. java 对象的定义是_浅析Java编程中类和对象的定义

    1,什么是类? 答:类是客观存在的,抽象的,概念的东西. 2,什么事对象? 答:对象是具体的,实际的,代表一个事物.例如:车是一个类,汽车,自行车就是他的对象. 关于类与对象的描述:类是对象的模版,对 ...

  9. java方法区对象类型_浅谈Java内存区域与对象创建过程

    一.java内存区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有的区域则 ...

最新文章

  1. 专为物联网开发的开源操作系统Contiki(转)
  2. TextInputLayout
  3. 洛谷 P1825 [USACO11OPEN]玉米田迷宫Corn Maze
  4. MFRC522开发笔记
  5. react 调用组件方法_React源码分析1 — 组件和对象的创建(createClass,createElement)...
  6. 嵌入式开发之网络心跳包---阻塞和非阻塞以及是否有必要心跳包heartbeat
  7. 8.Spring Cloud Alibaba教程:整合Seata分布式事务
  8. 9月份计算机应用基础统考,2018年9月计算机应用基础统考题库-网考计算机应用基础真题1...
  9. [中级]Java命令学习系列(五)——jhat
  10. QPW 公告表(tf_notice)
  11. error40;无法打开到SQL Server的连接,设置了Tcp/IP等也不能连接的问题
  12. Android图片压缩,不失真,上线项目
  13. mysql week统计_MySQL按周统计 WEEK 实例
  14. oracle容器部署,Linux docker oracle 部署
  15. oracle_最常见的 5 个导致节点重新启动、驱逐或 CRS 意外重启的问题
  16. instant java,Instant
  17. c语言3到7位水仙花数流程图_C语言入门基础整理
  18. html全局事件,HTML5全局属性和事件
  19. 替换url中某个参数的值或是添加某个参数的方法(js 分页上下页可以使用)
  20. 【图像分割】基于matlab模糊聚类算法FCM图像分割【含Matlab源码 084期】

热门文章

  1. 抖音xlog算法 hook分析记录 抖音xlog风控算法 抖音xlog参数分析
  2. 企业ERP项目实施,遇见问题与心得分享
  3. 【毕业设计】基于程序化生成和音频检测的生态仿真与3D内容生成系统----音频检测算法设计
  4. 安卓开发 之小白养成-Service详解
  5. 生成式AI时代,风险投资机构如何进行品牌建设?
  6. FZU 2243 Daxia like uber
  7. 【Java Se】封装与常用关键字
  8. 【云星数据---mesos实战系列002】:mesos全分布式部署实战009--修改marathon的默认端口
  9. java方法调用之动态调用多态(重写override)的实现原理——方法表
  10. 『Linux』默认头文件存储路径/usr/include