如何为OpenEndRange<LocalDate>实现map等高阶函数?
为OpenEndRange实现高阶函数支持
你的代码核心问题有两个:迭代器的hasNext()逻辑错误,以及可能未正确导入自定义的rangeUntil运算符导致使用了标准库的非Iterable实现。以下是修正方案:
1. 修复迭代器判断逻辑
你当前的hasNext()判断currentDate.plusDays(stepDays) <= endExclusive,会漏掉那些当前日期仍在开区间内,但加上步长后超出范围的元素。正确判断应直接检查当前日期是否小于结束日期(符合开区间start ≤ x < endExclusive的核心规则)。
2. 简化迭代器实现(可选)
用Kotlin标准库的generateSequence替代自定义迭代器类,代码更简洁且不易出错。
修正后的完整代码
package de.otto.di.extensions import java.time.LocalDate @OptIn(ExperimentalStdlibApi::class) class OpenEndLocalDateRange( override val start: LocalDate, override val endExclusive: LocalDate, private val stepDays: Long = 1 ) : Iterable<LocalDate>, OpenEndRange<LocalDate> { override fun iterator(): Iterator<LocalDate> = generateSequence(start) { it.plusDays(stepDays) } .takeWhile { it < endExclusive } .iterator() infix fun step(days: Long): OpenEndLocalDateRange = OpenEndLocalDateRange(start, endExclusive, days) } infix operator fun LocalDate.rangeUntil(to: LocalDate): OpenEndLocalDateRange = OpenEndLocalDateRange(this, to)
使用注意事项
在需要使用该开区间的代码文件中,必须导入自定义扩展函数:
import de.otto.di.extensions.rangeUntil
否则会默认使用Kotlin标准库为LocalDate生成的OpenEndRange实现(该实现不继承Iterable,无法使用map、forEach等高阶函数)。
测试示例
import de.otto.di.extensions.rangeUntil import java.time.LocalDate fun main() { val from = LocalDate.now().minusDays(10) val to = LocalDate.now() // 直接遍历 (from ..< to).forEach { println(it) } // 使用map转换 val nextDays = (from ..< to).step(2).map { it.plusDays(1) } println(nextDays) }
内容的提问来源于stack exchange,提问作者Ben Keil
相关产品推荐
相关产品推荐

