如何将scala.some转换成scala.mutable.Map?

How to convert scala.some to scala.mutable.Map?

我正在尝试编写代码来屏蔽嵌套的 json 字段..

 def maskRecursively(map :mutable.Map[String,Object]):mutable.Map[String,Object] ={
val maskColumns = PII_Data.getPIIData()
for((k,v) <- map){
  if(v.isInstanceOf[Map[String,Object]]){
    maskRecursively(map.get(k).asInstanceOf[mutable.Map[String,Object]])
  }else if(v.isInstanceOf[List[Object]]) {

  } else {
    if(maskColumns.contains(k)){map+=(k->"*****")}
  }

}


map }

从..调用此方法

val mapper = new ObjectMapper()
    mapper.registerModule(DefaultScalaModule)
    val result = mapper.readValue(jsonStr, classOf[ java.util.Map[String,Object] ])
    import scala.collection.JavaConverters._
    val myScalaMap = result.asScala
    maskRecursively(result.asScala)

我在尝试迭代嵌套的 json 对象时遇到错误..

Cannot cast value of type 'scala.Some' to type 'scala.collection.mutable.Map'

如何以这种方式递归复杂的嵌套 json 对象?

你的错误是

if(v.isInstanceOf[Map[String,Object]]){
    maskRecursively(map.get(k).asInstanceOf[mutable.Map[String,Object]])

有几个问题:

  1. 您检查 v 是否是 Map 的实例,然后尝试将其转换为 mutable.Map。它们在技术上是不同的类型(可变与不可变)。
  2. 您检查 v 的类型,但随后将强制转换应用于 map.get(k),这将是与 v 不同的值和类型。地图的 get 方法 returns 一个选项,因此是错误消息。
  3. 感谢 JVM 上的类型擦除,运行时将无法区分例如Map[String, Object]Map[SomethingElse, Whatever] - 两者在运行时看起来都像 Map。由于这个原因,编译器应该给你一个关于 isInstanceOf 调用的警告。

如果您执行 isInstanceOf / asInstanceOf 组合,请确保每次操作数都相同。你已经有了v,所以你不需要再从地图上查第二次了。并确保在两个 instanceOf 调用中使用相同的类型。

通过将其更改为

来解决此问题
if(v.isInstanceOf[mutable.Map[_, _]]){
    maskRecursively(v.asInstanceOf[mutable.Map[String,Object]])

经过一些挖掘,我能够解决这个问题..

    def maskJson(jsonStr: String): String = {
    implicit val formats = org.json4s.DefaultFormats
    val mapper = new ObjectMapper()
    mapper.registerModule(DefaultScalaModule)
    val result = mapper.readValue(jsonStr, classOf[Map[String, Object]])
    val maskedJson = maskRecursively(result)
    mapper.writeValueAsString(maskedJson)

  }


  def maskRecursively(map: Map[String, Object]): collection.mutable.Map[String, Object] = {
    val mutable = collection.mutable.Map[String, Object]()
    val maskColumns = PII_Data.getJsonPIIFields()
    for ((k, v) <- map) {
      if (v.isInstanceOf[Map[String, Object]]) {
        mutable += k -> maskRecursively(v.asInstanceOf[Map[String, Object]])
      } else if (v.isInstanceOf[List[Object]]) {
        val list = v.asInstanceOf[List[Map[String, Object]]].map(i => maskRecursively(i)).toList
        mutable += k -> list
      } else {
        if (maskColumns.contains(k)) {
          mutable += (k -> "*****")
        }
        else {
          mutable += k -> v
        }
      }
    }
    mutable
  }