如何遍历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
相关产品推荐
相关产品推荐

