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

Kotlin中如何避免MutableSet存储后元素顺序变更?

解决SharedPreferences保存StringSet后顺序丢失的问题

问题原因

SharedPreferences 的 getStringSet 方法返回的集合默认是无序的HashSet,即使存入时使用了有序的Set实现(如LinkedHashSet),框架内部序列化/反序列化过程会自动转换为无序集合,导致读取时元素顺序混乱。

解决方案:换用字符串存储有序集合

因为StringSet本身不保证顺序,推荐将有序集合序列化为字符串后存储,读取时再反序列化为有序Set(如LinkedHashSet),以此保留元素顺序。

方法1:JSON序列化(推荐,支持元素包含特殊字符)

使用Gson将LinkedHashSet序列化为JSON字符串存储:

// 读取方法
private fun getStrings(): MutableSet<String>? {
    val jsonStr = preferenceObject.getString("initList", null) ?: return mutableSetOf()
    return Gson().fromJson(jsonStr, object : TypeToken<LinkedHashSet<String>>() {}.type)
}

// 保存方法
private fun setStrings(list: MutableSet<String>?) {
    val targetSet = list?.let { LinkedHashSet(it) } ?: LinkedHashSet<String>()
    val jsonStr = Gson().toJson(targetSet)
    preferenceEditObject.putString("initList", jsonStr).apply()
}

方法2:分隔符拼接字符串(适用于元素无特殊分隔符的场景)

如果元素本身不含逗号,可直接用逗号拼接成字符串存储:

// 读取方法
private fun getStrings(): MutableSet<String>? {
    val str = preferenceObject.getString("initList", "") ?: return mutableSetOf()
    return if (str.isEmpty()) mutableSetOf() else LinkedHashSet(str.split(","))
}

// 保存方法
private fun setStrings(list: MutableSet<String>?) {
    val str = list?.joinToString(",") ?: ""
    preferenceEditObject.putString("initList", str).apply()
}

注意事项

  • 必须使用LinkedHashSet存储,它会严格保留元素的插入顺序,而HashSet/TreeSet无法保证顺序。
  • 如果使用分隔符拼接,需确保元素中不包含所选分隔符,否则会导致拆分错误;若无法避免,优先使用JSON序列化方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 20:25:18