简体   繁体   English

为什么当String.valueOf()在强制转换时toString不起作用

[英]Why toString does not work when String.valueOf() works at casting

I need to parse Json into Map[String,String] structure. 我需要将Json解析为Map [String,String]结构。 Json may contain numeric and string types as values. Json可能包含数字和字符串类型作为值。

So in order to store it as String I've applied toString method and it throws ClassCastException. 因此,为了将其存储为String,我应用了toString方法,并抛出ClassCastException。 However if String.valueOf() is applied everything is OK. 但是,如果应用String.valueOf(),则一切正常。

  1. Why so? 为什么这样?
  2. If there are better way to do such casting? 是否有更好的方法进行这种铸造?
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]
}

Because the pattern matching match the List type, but doesn't go all the way to all types inside the map, that's why you enter the Some clause. 因为模式匹配与List类型匹配,但并不会一直映射到地图中的所有类型,所以这就是为什么要输入Some子句的原因。

So, instead of the case Some(map: List[Map[String, String]]) => 因此,而不是这种case Some(map: List[Map[String, String]]) =>

Try do this: 尝试这样做:

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(s"Unexpected type $unexpectedType")
   }.toString}).toMap

That's how you can handle every value in your map safely. 这样便可以安全地处理地图中的每个值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM