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

Kotlin数据类:将多同类型属性转为List<Itinerary>的方法

改造ItineraryData为List结构的实现方案

针对JSON中itinerary_0到itinerary_9的键值对结构,要将原ItineraryData从10个单独属性改为包含List<Itinerary>的结构,需通过自定义序列化/反序列化逻辑实现,以下是两种常用Kotlin序列化库的具体方案:

方案一:使用kotlinx.serialization(官方序列化库)

1. 改造数据类结构

将ItineraryData改为包含List<Itinerary>的单一属性结构,并指定自定义反序列化器:

import kotlinx.serialization.Serializable
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.decodeFromJsonElement
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder

@Serializable(with = ItineraryDataDeserializer::class)
data class ItineraryData(val itineraries: List<Itinerary>)

object ItineraryDataDeserializer : DeserializationStrategy<ItineraryData> {
    override val descriptor: SerialDescriptor = buildClassSerialDescriptor("ItineraryData") {}

    override fun deserialize(decoder: Decoder): ItineraryData {
        // 解析JSON对象
        val jsonObject = decoder.decodeJsonElement().jsonObject
        // 筛选并排序itinerary_*键对应的内容,转为Itinerary列表
        val itineraries = jsonObject.entries
            .filter { it.key.startsWith("itinerary_") }
            .sortedBy { it.key.split("_")[1].toInt() }
            .map { Json.decodeFromJsonElement(Itinerary.serializer(), it.value) }
        return ItineraryData(itineraries)
    }
}

2. 使用方式

直接用Json.decodeFromString解析即可:

val jsonString = "你的JSON字符串"
val itineraryData = Json.decodeFromString<ItineraryData>(jsonString)

方案二:使用Gson

1. 改造数据类结构

定义包含List<Itinerary>的ItineraryData,并编写自定义TypeAdapter处理解析逻辑:

import com.google.gson.TypeAdapter
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonWriter

data class ItineraryData(val itineraries: List<Itinerary>)

class ItineraryDataTypeAdapter : TypeAdapter<ItineraryData>() {
    override fun write(out: JsonWriter, value: ItineraryData) {
        // 序列化时按原JSON格式输出(可选,若不需要序列化可省略)
        out.beginObject()
        value.itineraries.forEachIndexed { index, itinerary ->
            out.name("itinerary_$index")
            Gson().toJson(itinerary, itinerary.javaClass, out)
        }
        out.endObject()
    }

    override fun read(`in`: JsonReader): ItineraryData {
        val itineraries = mutableListOf<Itinerary>()
        val gson = Gson()
        `in`.beginObject()
        // 遍历JSON对象的键值对,筛选并解析itinerary_*内容
        while (`in`.hasNext()) {
            val key = `in`.nextName()
            if (key.startsWith("itinerary_")) {
                val itinerary = gson.fromJson(`in`, Itinerary::class.java)
                itineraries.add(itinerary)
            } else {
                `in`.skipValue() // 跳过无关键
            }
        }
        `in`.endObject()
        // 按序号排序,保证列表顺序与JSON中的itinerary_0到itinerary_9一致
        itineraries.sortBy { key ->
            key.split("_")[1].toInt()
        }
        return ItineraryData(itineraries)
    }
}

2. 使用方式

注册自定义TypeAdapter到Gson实例后进行解析:

val gson = GsonBuilder()
    .registerTypeAdapter(ItineraryData::class.java, ItineraryDataTypeAdapter())
    .create()
val jsonString = "你的JSON字符串"
val itineraryData = gson.fromJson(jsonString, ItineraryData::class.java)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 10:15:36