按 kotlinx.serialization 生成的键排序的映射

sil*_*vsk 2 kotlin kotlinx.serialization

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

@Serializable
class Example(val map: Map<String, Int>)
Run Code Online (Sandbox Code Playgroud)

它是连载的

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

那么生成的 json 应该是

{
    "map": {
        "a": 1,
        "b": 2,
        "c": 3
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

如何使用 获得排序后的 json kotlinx.serialization

(kotlin 1.4.0、kotlinx.serialization 1.0.0-RC)

sil*_*vsk 6

弄清楚了:

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
    ))
}
Run Code Online (Sandbox Code Playgroud)

(虽然很高兴能得到一个答案Map<Serializable, Serializable>