我需要将Json解析为Map [String,String]结构。 Json可能包含数字和字符串类型作为值。
因此,为了将其存储为String,我应用了toString方法,并抛出ClassCastException。但是,如果应用String.valueOf(),则一切正常。
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import scala.collection.Map
import scala.util.parsing.json.JSON
val mapper = new ObjectMapper()
mapper.registerModule(DefaultScalaModule)
val str = "[ { \"name\": \"VehicleType\", \"value\": 11 }, { \"name\": \"VehicleWeight\", \"value\": \"12000\" } ]"
val customfields = JSON.parseFull(str) match {
case Some(map: List[Map[String, String]]) =>
// map.map(map => {map("name") -> map("value").toString}).toMap
// that throws:
// java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.String
// at #worksheet#.$anonfun$customfields$1.apply(scratch.scala2:14)
// at #worksheet#.$anonfun$customfields$1.apply(scratch.scala2:14)
// at scala.collection.immutable.List.map(scratch.scala2:269)
// at #worksheet#.customfields$lzycompute(scratch.scala2:14)
// that works fine
map.map(map => {map("name") -> String.valueOf(map("value"))}).toMap
case _ => Map.empty[String, String]
}
答案 0 :(得分:1)
由于模式匹配与List类型匹配,但并不能一直映射到地图中的所有类型,所以这就是为什么要输入Some
子句的原因。
所以,而不是
case Some(map: List[Map[String, String]]) =>
尝试执行以下操作:
case Some(map: List[Map[String, _]]) =>
map.map(map => {map("name") ->
map("value") match {
case s: String => s
case i: java.lang.Number => i
case unexpectedType => throw Exception("Unexpected type $unexpectedType")
}.toString}).toMap
这就是您可以安全处理地图中每个值的方式。