首页 > 解决方案 > 按 kotlinx.serialization 生成的键排序的映射

问题描述

我需要用映射序列化一个类,以便映射中的键在 json 中排序。所以如果有一堂课

@Serializable
class Example(val map: Map<String, Int>)

它被序列化了

val example = Example(mapOf("b" to 2, "a" to 1, "c" to 3))
println(Json.encodeToString(example))

那么生成的json应该是

{
    "map": {
        "a": 1,
        "b": 2,
        "c": 3
    }
}

我尝试使用SortedMap而不是Map,但这会引发异常:

kotlinx.serialization.SerializationException:类“TreeMap”未在“SortedMap”范围内注册多态序列化

我怎样才能得到一个排序的 json 使用kotlinx.serialization

(kotlin 1.4.0,kotlinx.serialization 1.0.0-RC)

标签: kotlinkotlinx.serialization

解决方案


弄清楚了:

import kotlinx.serialization.*
import kotlinx.serialization.json.*
import kotlinx.serialization.builtins.*
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder

object SortedMapSerializer: KSerializer<Map<String, Int>> {
    private val mapSerializer = MapSerializer(String.serializer(), Int.serializer())
    
    override val descriptor: SerialDescriptor = mapSerializer.descriptor

    override fun serialize(encoder: Encoder, value: Map<String, Int>) {
        mapSerializer.serialize(encoder, value.toSortedMap())
    }

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

@Serializable
class Example(
    @Serializable(with = SortedMapSerializer::class)
    val map: Map<String, Int>
)

fun main() {
    val example = Example(mapOf("b" to 2, "c" to 3, "a" to 1))
    println(Json.encodeToString(
        example
    ))
}

(虽然很高兴有一个答案Map<Serializable, Serializable>


推荐阅读