Java 8-16环境下优化日程解析逻辑并实现获取最近或当前活跃日程的高效方案咨询
优化日程解析与实现目标方法的方案
嗨,针对你的需求,我从代码优化、目标方法实现和工具库推荐三个方面来给你梳理下:
一、优化现有解析代码(Java 8+风格)
你原来的嵌套split写法确实有点繁琐,而且Calendar是Java早期的时间API,可读性和易用性都不如Java 8引入的java.time包(比如LocalTime)。我们可以先重构ScheduleCalendar类,再简化解析逻辑:
1. 重构ScheduleCalendar类
用LocalTime代替Calendar,它专门用于处理无日期的时间,代码更简洁直观:
import java.time.LocalTime; public static class ScheduleCalendar { private final LocalTime startTime; private final LocalTime endTime; public ScheduleCalendar(LocalTime startTime, LocalTime endTime) { this.startTime = startTime; this.endTime = endTime; } // 修正isNow方法的逻辑(原逻辑写反了) public boolean isNow() { LocalTime now = LocalTime.now(); return now.isAfter(startTime) && now.isBefore(endTime); } // 新增判断是否为未来日程的方法 public boolean isUpcoming() { return startTime.isAfter(LocalTime.now()); } // Getters public LocalTime getStartTime() { return startTime; } public LocalTime getEndTime() { return endTime; } }
注意:你原来的
isNow方法逻辑是反的,已经帮你修正了,正确的判断应该是当前时间在开始和结束之间。
2. 简化解析逻辑
用Stream API替代原来的forEach写法,代码更流畅,还能自动过滤分割后可能出现的空字符串:
import java.time.LocalTime; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; private final List<ScheduleCalendar> _schedules = new ArrayList<>(); // 解析方法 public void parseSchedule(String scheduleStr) { _schedules.addAll( List.of(scheduleStr.replaceAll("\\s", "").split(";")) .stream() .filter(segment -> !segment.isBlank()) // 过滤空的时间段 .map(segment -> { String[] timePair = segment.split("-"); LocalTime start = LocalTime.parse(timePair[0]); LocalTime end = LocalTime.parse(timePair[1]); return new ScheduleCalendar(start, end); }) .collect(Collectors.toList()) ); }
这里直接用LocalTime.parse()就能解析HH:mm格式的字符串,省去了手动拆分小时分钟的麻烦,非常省心。
二、实现获取当前活跃/最近待执行日程的方法
我们可以写一个方法,按优先级处理:先找当前正在进行的日程,找不到就找最近的未来日程,代码用Stream就能简洁实现:
public ScheduleCalendar getCurrentOrNearestUpcoming() { LocalTime now = LocalTime.now(); // 1. 先找当前活跃的日程 ScheduleCalendar active = _schedules.stream() .filter(ScheduleCalendar::isNow) .findFirst() .orElse(null); if (active != null) { return active; } // 2. 找不到活跃的,找最近的未来日程(按开始时间排序取第一个) return _schedules.stream() .filter(ScheduleCalendar::isUpcoming) .sorted((s1, s2) -> s1.getStartTime().compareTo(s2.getStartTime())) .findFirst() .orElse(null); // 没有未来日程返回null,也可以根据需求返回默认值 }
如果你的日程可能跨天(比如23:00-01:00),那需要额外处理,但从你的原始格式来看应该是当天的时间段,这个逻辑就足够了。
三、第三方工具库推荐
如果想进一步简化字符串处理或时间操作,这些库可以考虑:
- Guava:它的
Splitter类比原生split更灵活,比如可以直接忽略空字符串和空格,写法更简洁:import com.google.common.base.Splitter; // 用Guava分割字符串 Splitter.on(";") .trimResults() .omitEmptyStrings() .split(scheduleStr) - Apache Commons Lang:
StringUtils类的splitByWholeSeparatorPreserveAllTokens等方法可以更安全地处理字符串分割,避免空指针或意外的空字符串。 - 其实Java 8+的
java.time包已经足够强大,大部分时间操作不需要额外依赖,推荐优先使用原生API。
内容的提问来源于stack exchange,提问作者Girls are beautiful
相关产品推荐
相关产品推荐

