按kotlinx.serialization生成的键排序的映射
我需要用映射序列化一个类,以便映射中的键在json中排序。如果有课的话按kotlinx.serialization生成的键排序的映射,kotlin,kotlinx.serialization,Kotlin,Kotlinx.serialization,我需要用映射序列化一个类,以便映射中的键在json中排序。如果有课的话 @Serializable class Example(val map: Map<String, Int>) 然后生成的json应该是 { "map": { "a": 1, "b": 2, "c": 3 } } 我尝试使用SortedMap而不是Map,但这引发了一个
@Serializable
class Example(val map: Map<String, Int>)
然后生成的json应该是
{
"map": {
"a": 1,
"b": 2,
"c": 3
}
}
我尝试使用SortedMap
而不是Map
,但这引发了一个异常:
kotlinx.serialization.SerializationException:类“TreeMap”未在“SortedMap”的作用域中注册为多态序列化
如何使用kotlinx.serialization
获取排序后的json
(kotlin 1.4.0,kotlin x.1.0.0-RC)找到了答案:
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
))
}
导入kotlinx.serialization*
导入kotlinx.serialization.json*
导入kotlinx.serialization.builtins*
导入kotlinx.serialization.descriptors.SerialDescriptor
导入kotlinx.serialization.encoding.Decoder
导入kotlinx.serialization.encoding.Encoder
对象分类容器序列化器:k序列化器{
private val mapSerializer=mapSerializer(String.serializer(),Int.serializer())
覆盖val描述符:SerialDescriptor=mapSerializer.descriptor
重写有趣的序列化(编码器:编码器,值:映射){
序列化(编码器,值.toSortedMap())
}
重写有趣的反序列化(解码器:解码器):映射{
返回mapSerializer.deserialize(解码器)
}
}
@可序列化
课例(
@可序列化(with=SortedMapSerializer::class)
val地图:地图
)
主要内容(){
val示例=示例(mapOf(“b”到2,“c”到3,“a”到1))
println(Json.encodeToString(
例子
))
}
(虽然对于
Map
有一个答案是很好的,但是为什么您需要以序列化的形式对其进行排序?如果您只想对其进行反序列化,顺序应该无关紧要。如果您要在其他地方使用它,那么您自己进行序列化,而不是使用系统的(如果它类似于标准Java序列化,则只用于再次反序列化)@gidds-我需要它不仅是为了反序列化。我生成的这个json也可以由其他软件编辑。它也可以提交给git。因此,如果对它进行排序,那么可以很容易地看到差异,而且它在git中占用的空间也更少(这是一个相当大的json)。json格式是一个标准,它实际上可以让其他工具轻松访问,也可以手动查看更改。事实上,如果我只需要在内部对其进行序列化,那么它就没有多大关系,我可以使用未排序的映射或一些自定义序列化。
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
))
}