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

如何遍历SharedPreference时间键并筛选非零值存入列表

解决方案:遍历SharedPreference中按分钟倒推的非零值时间键

当然可行!这个需求完全能实现,核心逻辑就是从当前时间开始,以分钟为步长逐次倒推,把每个时间转换成你存储时用的键格式,去SharedPreference里查对应的值,只要值非零就把这个键放进结果列表就行。

我给你拆解下具体实现步骤,再附上代码示例:

1. 先搞定时间格式的统一

你存储的键是19/08/2020_13:12这种(下划线分隔日期和时间),遍历的时候要确保生成的键和这个格式完全匹配——用dd/MM/yyyy_HH:mm的格式规则(注意是日/月/年的顺序,24小时制),这样才能精准匹配到SharedPreference里的键。

2. 实现时间倒推的循环逻辑

用Java 8+的LocalDateTime(Android API 26+支持,低版本可以用ThreeTenABP兼容)来处理时间加减,比传统的Calendar简洁太多。从当前时间开始,每次减1分钟,直到达到你设定的结束时间(比如示例里的19/08/2018 05:08)。

3. 查询并收集非零值的键

对每个生成的时间键,调用SharedPreferences.getInt(key, 0)(假设你存的是int类型的值),如果返回值不等于0,就把这个键加入结果列表。

基础实现代码(Kotlin)

import android.content.SharedPreferences
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

fun getNonZeroTimeKeys(sharedPref: SharedPreferences, endTime: LocalDateTime): List<String> {
    val result = mutableListOf<String>()
    var currentTime = LocalDateTime.now()
    
    // 定义和存储时一致的时间格式器
    val timeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy_HH:mm")
    
    // 循环倒推时间,直到当前时间早于等于结束时间
    while (currentTime.isAfter(endTime)) {
        val timeKey = currentTime.format(timeFormatter)
        // 查询值,默认返回0
        val storedValue = sharedPref.getInt(timeKey, 0)
        if (storedValue != 0) {
            result.add(timeKey)
        }
        // 倒推1分钟
        currentTime = currentTime.minusMinutes(1)
    }
    
    // 额外检查结束时间的键是否符合条件
    val endTimeKey = endTime.format(timeFormatter)
    if (sharedPref.getInt(endTimeKey, 0) != 0) {
        result.add(endTimeKey)
    }
    
    return result
}

性能优化建议(针对大时间范围)

如果你的时间跨度很大(比如示例里的2年),直接循环倒推会有上百万次迭代,效率很低。可以换个思路:先把SharedPreference里所有键值对取出来,筛选出符合时间范围且值非零的键,再排序:

fun getNonZeroTimeKeysOptimized(sharedPref: SharedPreferences, startTime: LocalDateTime, endTime: LocalDateTime): List<String> {
    val timeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy_HH:mm")
    
    return sharedPref.all.filter { (key, value) ->
        // 安全解析键为时间,避免格式错误的键抛出异常
        runCatching {
            val keyTime = LocalDateTime.parse(key, timeFormatter)
            // 判断时间是否在范围内,且值非零
            keyTime.isAfter(startTime) && keyTime.isBefore(endTime) && (value as Int) != 0
        }.getOrDefault(false)
    }.keys.toList()
        .sortedByDescending { LocalDateTime.parse(it, timeFormatter) } // 按时间倒序排列
}

注意事项

  • 一定要保证时间格式完全一致:比如日期分隔符是/不是-,日期时间之间是_不是空格,小时是24小时制,差一点都查不到对应的值。
  • 明确循环的终止条件:比如是否要包含结束时间,避免漏查或者死循环。
  • 低版本Android兼容:如果你的APP要兼容API 26以下,记得引入ThreeTenABP库来使用LocalDateTime。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 21:52:41