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

如何将含递增键作为ID的JSON字符串映射到Kotlin数据类

问题原因

你的JSON结构是顶级对象直接包含数字字符串键对应的Item对象,但你定义的DataClassWithKeys期望JSON有一个名为items的顶级键,内部才是Map结构——这种结构不匹配导致解析器找不到对应键,从而报错。

解决方案

方法一:直接解析为Map(推荐)

不需要外层数据类,直接将JSON解析成Map<Int, Item>,Kotlinx Serialization原生支持这种结构的映射:

@Serializable
data class Item(
    val title: Int,
    val artist: String,
    val album: String
)

// 直接解析JSON为Map
val itemMap = Json.decodeFromString<Map<Int, Item>>(jsonString)

解析时,JSON中的字符串键(如"0"、"1")会自动转换为Int类型,对应的值会被解析为Item对象。

方法二:保留外层数据类(自定义适配)

如果必须使用外层数据类,可以通过自定义序列化器,将JSON的顶级键映射到items字段:

import kotlinx.serialization.*
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.serializer

@Serializable
data class DataClassWithKeys(
    @Serializable(with = TopLevelMapSerializer::class)
    val items: Map<Int, Item>
) {
    @Serializable
    data class Item(
        val title: Int,
        val artist: String,
        val album: String
    )

    // 自定义序列化器:将JSON顶级键值对直接映射为Map
    object TopLevelMapSerializer : KSerializer<Map<Int, Item>> {
        private val delegate = MapSerializer(Int.serializer(), Item.serializer())
        override val descriptor: SerialDescriptor = delegate.descriptor

        override fun serialize(encoder: Encoder, value: Map<Int, Item>) {
            delegate.serialize(encoder, value)
        }

        override fun deserialize(decoder: Decoder): Map<Int, Item> {
            return delegate.deserialize(decoder)
        }
    }
}

// 解析调用
val dataClassWithMap = Json.decodeFromString<DataClassWithKeys>(jsonString)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 04:16:03