Kotlin中使用Retrofit对动态键JSON数据建模的高效方法
解决方案
你遇到的是JSON外层为动态数字键的结构,不需要为每个键创建单独的数据类,仅需要用Map容器包裹你已经定义好的ReleasedPokemonModel即可,总共仅需1个自定义数据类即可完成适配。
核心逻辑
你给出的JSON结构本质是键为字符串格式数字、值为宝可梦对象的映射集合,所有主流JSON序列化库都原生支持Map类型的解析,不需要为每个动态键声明固定字段。
各序列化库实现示例
1. Gson
直接解析为Map类型即可:
// 你定义的原有数据类无需修改 data class ReleasedPokemonModel( val id: Int, val name: String ) // 解析代码 val gson = Gson() val pokemonMap: Map<String, ReleasedPokemonModel> = gson.fromJson( yourJsonString, object : TypeToken<Map<String, ReleasedPokemonModel>>() {}.type ) // 可按需转换为列表 val pokemonList = pokemonMap.values.toList()
2. Kotlinx Serialization
给你的数据类添加序列化注解后直接解析:
import kotlinx.serialization.Serializable import kotlinx.serialization.json.Json @Serializable data class ReleasedPokemonModel( val id: Int, val name: String ) // 解析代码 val pokemonMap = Json.decodeFromString<Map<String, ReleasedPokemonModel>>(yourJsonString)
3. Moshi
val moshi = Moshi.Builder().build() val mapType = Types.newParameterizedType( Map::class.java, String::class.java, ReleasedPokemonModel::class.java ) val adapter = moshi.adapter<Map<String, ReleasedPokemonModel>>(mapType) val pokemonMap = adapter.fromJson(yourJsonString)
可选校验
如果需要保证外层数字键和宝可梦内部id一致,可在解析完成后增加校验逻辑:
val validPokemonList = pokemonMap.filter { (key, pokemon) -> key.toIntOrNull() == pokemon.id }.values.toList()
内容的提问来源于stack exchange,提问作者Brian Mason
相关产品推荐
相关产品推荐

