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

Android Retrofit如何自定义模型类实现响应数据自动映射至Map

用Retrofit+Gson自动映射指定字段为LinkedHashMap

需求说明

常规使用Retrofit+Gson解析API返回的JSON时,会创建Temperature、Data、Cold、Hot、Widget等对应的数据类。现在需要将Widget改为包含LinkedHashMap<Int, Int>的结构,自动把Hot类的key字段作为Map的键,Cold类的value字段作为Map的值,无需手动循环提取赋值,通过自定义转换器工厂实现自动化处理。

实现步骤

1. 定义目标数据结构

调整Widget为LinkedHashMap<Int, Int>类型,保留必要的层级结构:

data class Temperature(
    val data: Data
)

data class Data(
    val widget: LinkedHashMap<Int, Int>
)

2. 自定义Gson TypeAdapter

编写自定义TypeAdapter处理原JSON中widget节点的解析逻辑,将hot数组的key和cold数组的value映射到LinkedHashMap:

class WidgetMapAdapter : TypeAdapter<LinkedHashMap<Int, Int>>() {
    override fun write(writer: JsonWriter, map: LinkedHashMap<Int, Int>?) {
        // 若无需序列化,可跳过此方法;如需序列化则实现对应逻辑
        writer.beginObject()
        map?.forEach { (key, value) ->
            writer.name(key.toString()).value(value)
        }
        writer.endObject()
    }

    override fun read(reader: JsonReader): LinkedHashMap<Int, Int> {
        val resultMap = LinkedHashMap<Int, Int>()
        val hotKeys = mutableListOf<Int>()

        reader.beginObject()
        while (reader.hasNext()) {
            when (reader.nextName()) {
                "hot" -> {
                    // 解析hot数组的key字段
                    reader.beginArray()
                    while (reader.hasNext()) {
                        reader.beginObject()
                        while (reader.hasNext()) {
                            if (reader.nextName() == "key") {
                                hotKeys.add(reader.nextInt())
                            } else {
                                reader.skipValue()
                            }
                        }
                        reader.endObject()
                    }
                    reader.endArray()
                }
                "cold" -> {
                    // 解析cold数组的value字段,与hot的key一一对应
                    reader.beginArray()
                    var index = 0
                    while (reader.hasNext()) {
                        reader.beginObject()
                        while (reader.hasNext()) {
                            if (reader.nextName() == "value" && index < hotKeys.size) {
                                resultMap[hotKeys[index]] = reader.nextInt()
                                index++
                            } else {
                                reader.skipValue()
                            }
                        }
                        reader.endObject()
                    }
                    reader.endArray()
                }
                else -> reader.skipValue()
            }
        }
        reader.endObject()
        return resultMap
    }
}

3. 注册适配器到Gson实例

创建Gson时注册自定义适配器,让Gson识别并使用该解析逻辑:

val customGson = GsonBuilder()
    .registerTypeAdapter(LinkedHashMap::class.java, WidgetMapAdapter())
    .create()

4. 配置Retrofit使用自定义Gson

在Retrofit构建时指定这个自定义Gson实例,替换默认的解析逻辑:

val retrofit = Retrofit.Builder()
    .baseUrl("你的API基础地址")
    .addConverterFactory(GsonConverterFactory.create(customGson))
    .build()

关键提示

  • 上述适配器的解析逻辑基于常见的JSON结构(widget包含hot和cold两个数组),请根据实际API返回的JSON格式调整字段名和结构判断逻辑。
  • 若hot和cold数组长度不一致,需添加边界处理(比如忽略多余的键或值)。
  • 如果需要将LinkedHashMap序列化为原JSON格式,完善write方法即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 00:01:39