You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Calendar循环add日期时disabledDays仅存入单条日期异常

问题原因

核心问题是你全程只创建了1个可变的Calendar实例,循环过程中所有操作都在修改这同一个对象的内部状态:

  • 第一次循环时,你把dayCalendar对象的引用添加到了disabledDays集合中,此时集合里存的是指向这个唯一实例的引用
  • 后续循环调用dayCalendar.add(Calendar.DAY_OF_MONTH, 1)时,修改的就是这个已经存在于集合中的实例本身的时间值,集合里存的引用指向的对象时间会跟着同步变化
  • 执行!disabledDays.contains(dayCalendar)判断时,因为集合里本来就存了这个对象的引用,判断结果永远为false,不会再执行添加操作,最终集合里只会保留1个元素,且这个元素的时间是循环全部执行完后的最终日期,完全不符合预期。
修复方法

每次循环生成新日期时,都要基于初始时间克隆出一个独立的Calendar实例再操作,确保存入集合的每个对象都是独立的、不会被后续修改的实例。
修复后的代码如下:

val baseCalendar = Calendar.getInstance().apply {
    time = entryDateC.time
}
for (day in 1..howManyDays) {
    // 每次循环克隆新实例,避免复用同一个可变对象
    val dayCalendar = (baseCalendar.clone() as Calendar).apply {
        add(Calendar.DAY_OF_MONTH, day)
    }
    if (!disabledDays.contains(dayCalendar)) {
        disabledDays.add(dayCalendar)
    }
}

如果你使用Java 8+或Android API 26及以上版本,更推荐用不可变的java.time包下的LocalDate类处理日期,从根源上避免可变对象复用导致的这类问题,示例代码:

import java.time.LocalDate
import java.time.ZoneId

// 先将初始Date类型转换为不可变的LocalDate
val baseDate = entryDateC.toInstant()
    .atZone(ZoneId.systemDefault())
    .toLocalDate()
for (day in 1..howManyDays) {
    // plusDays会返回全新的LocalDate实例,不存在复用修改问题
    val targetDate = baseDate.plusDays(day.toLong())
    if (!disabledDays.contains(targetDate)) {
        disabledDays.add(targetDate)
    }
}

内容的提问来源于stack exchange,提问作者Mark George

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 16:45:39