Scala如何更新Map[String, Map]嵌套结构内的指定字段值
Scala修改嵌套Map指定路径值的解决方案
前置问题修正
你原有的反序列化代码存在类型匹配错误:你指定的目标类型是Map[String, String],但你的JSON是多层嵌套结构,值并不全为String,会导致解析异常或类型擦除问题,建议先给Jackson注册Scala模块,再指定正确的嵌套Map类型进行反序列化。
方案1:使用可变Map(修改操作简单高效)
适合不需要线程安全、需要多次修改Map内容的场景,代码示例如下:
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.scala.DefaultScalaModule import scala.collection.mutable.Map // 注册Scala模块,解决Jackson解析Scala集合的兼容性问题 val mapper = new ObjectMapper() mapper.registerModule(DefaultScalaModule) // 反序列化为嵌套可变Map结构 val dataMap = mapper.readValue(jsonData, classOf[Map[String, Map[String, Any]]]) // 逐层定位到目标路径并修改值 dataMap("2021-11-24") .asInstanceOf[Map[String, Map[String, String]]]("Execution_Steps") .put("Step_2", "OK")
方案2:使用不可变Map(符合Scala函数式编程规范,线程安全)
Scala默认的Map是不可变类型,修改时需要逐层复制生成新的Map,代码示例如下:
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.scala.DefaultScalaModule val mapper = new ObjectMapper() mapper.registerModule(DefaultScalaModule) // 反序列化为不可变嵌套Map val dataMap: Map[String, Map[String, Any]] = mapper.readValue(jsonData, classOf[Map[String, Map[String, Any]]]) // 逐层更新生成新的Map val oldExecSteps = dataMap("2021-11-24")("Execution_Steps").asInstanceOf[Map[String, String]] val newExecSteps = oldExecSteps.updated("Step_2", "OK") val newDateInfo = dataMap("2021-11-24").updated("Execution_Steps", newExecSteps) val finalDataMap = dataMap.updated("2021-11-24", newDateInfo)
注意事项
如果未给Jackson注册Scala模块,反序列化得到的会是Java的Map类型,可通过scala.jdk.CollectionConverters中的asScala方法将其转换为Scala的Map类型后再操作。
内容的提问来源于stack exchange,提问作者Anderson Dutra
相关产品推荐
相关产品推荐

