是否可以使用Json4s将JSON解码为ListMap

时间:2017-12-30 23:50:37

标签: json scala json4s

如果解码为HashMap,Json4s解码的结果经常会扰乱JObject中的元素序列,所以我尝试将其解码为ListMap。但是,当我运行以下简单程序时,似乎无法做到这一点:

val v: ListMap[String, Int] = ListMap("a" -> 1, "b" -> 2)
val json = JsonMethods.compact(Extraction.decompose(v))
val v2 = Extraction.extract[ListMap[String, Int]](JsonMethods.parse(json))
assert(v == v2)

抛出以下错误消息:

scala.collection.immutable.Map$Map2 cannot be cast to scala.collection.immutable.ListMap
java.lang.ClassCastException: scala.collection.immutable.Map$Map2 cannot be cast to scala.collection.immutable.ListMap

有没有一种简单的方法可以解决这个问题?或者我应该切换到更新的Json库(Argonaut / Circe)吗?

2 个答案:

答案 0 :(得分:0)

不,你不能这样做。至少不是这样的。根据{{​​3}}

  

对象是一组无序名称/值对。

所有标准库都以这种方式对待它。这意味着当/ library执行初始解析到中间数据结构时,订单已经被加扰。此外,您甚至可以保证JSON不是$ brew uninstall --force carthage 而是{"a":1, "b":2}

保留顺序的唯一方法是以强制执行顺序的方式存储在JSON内部,并且唯一的这样的事情是有序的值列表,也就是数组。所以你可以这样做:

{"b":2, "a":1}

打印

  

' {" C":1," AAAA":2" BBBB":3," AABB&#34 ;: 4," BBAA":5}' =>图(AaAa - > 2,BBBB - > 3,AaBB - > 4,BBAa - > 5,c - > 1)   
' [{" c":1},{" AaAa":2},{" BBBB":3},{& #34; AABB&#34:4},{" BBAA":5}]' => ListMap(c - > 1,AaAa - > 2,BBBB - > 3,AaBB - > 4,BBAa - > 5)

答案 1 :(得分:0)

这是一个library,它支持所有 Scala集合,因此您可以轻松地解析和序列化ListMap,也可以按顺序序列化案例类字段声明:

libraryDependencies ++= Seq(
  "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-core" % "0.29.2" % Compile, 
  "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-macros" % "0.29.2" % Provided // required only in compile-time
)

import com.github.plokhotnyuk.jsoniter_scala.macros._
import com.github.plokhotnyuk.jsoniter_scala.core._

val codec = JsonCodecMaker.make[ListMap[String, Int]](CodecMakerConfig())
val v: ListMap[String, Int] = ListMap("a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4, "e" -> 5)
val json = writeToArray(codec, v)
val v2 = readFromArray(codec, json)
require(v == v2)