Kotlin中求多个ClosedRange<LocalDate>实例交集的最惯用方法
计算ClosedRange列表的交集(Kotlin惯用实现)
核心思路
多个区间的交集,本质是逐步迭代取两两区间的重叠部分——从第一个区间开始,依次和后续每个区间计算交集,一旦中途出现无重叠的情况,整个列表就没有共同交集,直接返回null即可。
实现步骤
- 给
ClosedRange<LocalDate>添加扩展函数:实现两个区间的交集计算,返回可能为空的区间(因为两个区间可能不重叠)。 - 用集合
fold操作累积计算:对区间列表进行折叠操作,从第一个区间开始,依次与后续区间取交集,中途若得到null则终止流程。
完整代码示例
import java.time.LocalDate // 扩展函数:计算两个LocalDate区间的交集 fun ClosedRange<LocalDate>.intersectWith(other: ClosedRange<LocalDate>): ClosedRange<LocalDate>? { val start = maxOf(start, other.start) val end = minOf(endInclusive, other.endInclusive) return if (start <= end) start..end else null } // 计算区间列表的共同交集 fun List<ClosedRange<LocalDate>>.computeIntersection(): ClosedRange<LocalDate>? { return if (isEmpty()) null else fold(first()) { currentIntersection, nextRange -> currentIntersection?.intersectWith(nextRange) ?: return null } }
代码说明
- 扩展函数
intersectWith:复用Kotlin标准库的maxOf和minOf计算交集的起止日期,若起始日期晚于结束日期则返回null(表示无交集)。 computeIntersection函数:- 空列表直接返回
null(可根据业务需求调整,比如返回空区间,但通常无实际意义)。 - 使用
fold进行累积计算,每次用当前的交集结果和下一个区间取交集,一旦出现null就直接返回,避免不必要的计算。
- 空列表直接返回
- 空安全处理:全程使用可空类型处理无交集的情况,符合Kotlin的空安全设计原则。
使用示例
fun main() { val date1 = LocalDate.of(2024, 1, 1)..LocalDate.of(2024, 6, 30) val date2 = LocalDate.of(2024, 3, 1)..LocalDate.of(2024, 9, 30) val date3 = LocalDate.of(2024, 4, 1)..LocalDate.of(2024, 8, 31) val ranges = listOf(date1, date2, date3) val intersection = ranges.computeIntersection() println(intersection) // 输出:2024-04-01..2024-06-30 }
内容的提问来源于stack exchange,提问作者Hermann.Gruber
相关产品推荐
相关产品推荐

