Kotlin中修改嵌套JSON单个元素值并实现POST更新的方法
解决方法
1. 修正SharedPreferences键名错误
存数据时用的键是"carList",但接收时写成了"cars",这会导致获取到的carsJson为null,后续解析完全无效。修正接收代码的键名:
val carsJson = sharedPreferences.getString("carList", null)
2. 处理带逗号的里程字符串与Int的互转
原JSON中milesDriven是带千分位逗号的字符串(如"100,000"),但CarModel中定义为Int类型,Gson默认无法完成这种转换,需要自定义序列化/反序列化逻辑:
自定义TypeAdapter
class MilesTypeAdapter : TypeAdapter<Int>() { override fun write(out: JsonWriter, value: Int?) { // 序列化时将Int转为带千分位逗号的字符串 val formatted = String.format("%,d", value) out.value(formatted) } override fun read(`in`: JsonReader): Int { // 反序列化时去掉逗号转成Int val str = `in`.nextString().replace(",", "") return str.toInt() } }
初始化Gson时注册该Adapter
val gson = GsonBuilder() .registerTypeAdapter(Int::class.java, MilesTypeAdapter()) .create()
不管是存SharedPreferences、解析数据还是POST序列化,都要用这个自定义的Gson实例,不能用默认的Gson()。
3. 正确修改Kia的里程
方式一:遍历列表直接修改(适合可变属性场景)
carsList.forEach { car -> if (car.brand == "Kia") { car.milesDriven = 30000 // 这里用Int,序列化时会自动转成带逗号的字符串 } }
方式二:用map生成新列表(适合不可变对象场景)
val updatedCarsList = carsList.map { car -> if (car.brand == "Kia") { car.copy(milesDriven = 30000) } else { car } }.toCollection(ArrayList())
4. 序列化并验证结果
修改完成后,用自定义的Gson转成符合数据库要求的JSON字符串,此时Kia的里程会变成"30,000":
val postJson = gson.toJson(updatedCarsList) // 或者修改后的carsList println("cars: $postJson")
完整接收并修改的代码示例
// SecondActivity中完整代码 val sharedPreferences = getSharedPreferences("sharedPreferences", MODE_PRIVATE) val carsJson = sharedPreferences.getString("carList", null) // 自定义Gson实例 val gson = GsonBuilder() .registerTypeAdapter(Int::class.java, MilesTypeAdapter()) .create() val type: Type = object : TypeToken<ArrayList<CarModel>>() {}.type val carsList: ArrayList<CarModel> = gson.fromJson(carsJson, type) // 修改Kia的里程 carsList.forEach { if (it.brand == "Kia") { it.milesDriven = 30000 } } // 若POST需要和原JSON一致的外层"cars"键,包装成对应结构 data class CarRequest(val cars: List<CarModel>) val postJson = gson.toJson(CarRequest(carsList)) println("cars: $postJson")
内容的提问来源于stack exchange,提问作者DJTalls
相关产品推荐
相关产品推荐

