Groovy 4.x遍历LocalDate范围报错,原Groovy3.x代码失效求修复方案
Groovy 4.x中LocalDate范围遍历失败的修复方案
问题场景
以下代码在Groovy 3.x中可正常执行,但在Groovy 4.x中抛出异常:
LocalDate startDate = LocalDate.of(2023, Month.JULY, 1) LocalDate endDate = LocalDate.of(2023, Month.JULY, 31) LocalDate[] businessDates = (startDate..endDate).collect() businessDates.stream().forEach { print it }
抛出的异常信息:
Caught: groovy.lang.MissingMethodException: No signature of method: java.time.LocalDate.next() is applicable for argument types: () values: [] Possible solutions: get(java.time.temporal.TemporalField), wait(), now(), wait(long), now(java.time.Clock), now(java.time.ZoneId) groovy.lang.MissingMethodException: No signature of method: java.time.LocalDate.next() is applicable for argument types: () values: [] Possible solutions: get(java.time.temporal.TemporalField), wait(), now(), wait(long), now(java.time.Clock), now(java.time.ZoneId) at Main.run(Main.groovy:4) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
原因分析
Groovy 3.x会为实现Comparable接口的类自动生成next()/previous()方法,以此支持..范围操作符的遍历逻辑。但Groovy 4.x移除了这一自动生成逻辑,导致LocalDate无法再通过startDate..endDate生成日期序列,触发next()方法不存在的异常。
修复方案
方案1:使用Java原生datesUntil方法(推荐)
利用Java 8+为LocalDate提供的datesUntil方法生成日期流,注意该方法默认不包含结束日期,需传入endDate.plusDays(1)来包含最后一天:
LocalDate startDate = LocalDate.of(2023, Month.JULY, 1) LocalDate endDate = LocalDate.of(2023, Month.JULY, 31) LocalDate[] businessDates = startDate.datesUntil(endDate.plusDays(1)).toArray(LocalDate[]::new) businessDates.stream().forEach { print it }
方案2:手动循环遍历日期
通过手动循环递增日期,收集成列表后再转为数组:
LocalDate startDate = LocalDate.of(2023, Month.JULY, 1) LocalDate endDate = LocalDate.of(2023, Month.JULY, 31) List<LocalDate> dateList = [] LocalDate currentDate = startDate while (!currentDate.isAfter(endDate)) { dateList.add(currentDate) currentDate = currentDate.plusDays(1) } LocalDate[] businessDates = dateList.toArray(new LocalDate[0]) businessDates.stream().forEach { print it }
方案3:添加Groovy扩展方法(全局复用)
如果需要在多处复用..范围遍历逻辑,可以为LocalDate手动添加next()扩展方法,让原代码保持不变:
// 定义LocalDate的扩展方法 extension module java.time.LocalDate { LocalDate next() { return plusDays(1) } } // 原代码可直接正常运行 LocalDate startDate = LocalDate.of(2023, Month.JULY, 1) LocalDate endDate = LocalDate.of(2023, Month.JULY, 31) LocalDate[] businessDates = (startDate..endDate).collect() businessDates.stream().forEach { print it }
内容的提问来源于stack exchange,提问作者developer
相关产品推荐
相关产品推荐

