使用 jackson 库,我从文件(文件的每一行都是一个JSON对象)读取json数据,并将其解析为 String 和的映射对象任何。我的目标是将指定的键(ID和文本)保存到集合中。
val input = scala.io.Source.fromFile("data.json").getLines()
val mapper = new ObjectMapper() with DefaultScalaModule
val data_collection = mutable.HashMap.empty[Int, String]
for (i <- input){
val parsedJson = mapper.readValue[Map[String, Any]](i)
data_collection.put(
parsedJson.get("id"),
parsedJson.get("text")
)
但是由于 parsedJson 映射中的值具有 Any 类型,因此获得了诸如 id 和 text ,它将返回 Some(value),而不仅仅是具有适当类型的值。我希望 id 键的值是Integer,而 text 的值是String。 运行代码时出现错误:
Error:(31, 23) type mismatch;
found : Option[Any]
required: Int
parsedJson.get("id"),
以下是文件中JSON数据的示例:
{"text": "Hello How are you", "id": 1}
在Scala中是否可以将id值解析为Int并将文本值解析为String,或者至少将Some(value)转换为Int或String类型的值?
答案 0 :(得分:2)
尝试以下代码:
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import
com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper
val input = scala.io.Source.fromFile("data.json").getLines()
val mapper = new ObjectMapper() with ScalaObjectMapper
mapper.registerModule(DefaultScalaModule)
val obj = mapper.readValue[Map[String, Any]](input)
val data_collection = mutable.HashMap.empty[Int, String]
for (i <- c) {
data_collection.put(
obj.get("id").fold(0)(_.toString.toInt),
obj.get("text").fold("")(_.toString)
)
}
println(data_collection) // Map(1 -> Hello How are you)
答案 1 :(得分:1)
如果您想从Map
而不是 Option 中获取纯值,则可以使用()
(apply
)方法-但是它将如果找不到密钥,则引发异常。
第二,Scala类型的系统是静态的而不是动态的,如果您拥有Any
,它将在运行时不会更改为Int
或String
,并且编译器将失败-不过,您可以使用asInstanceOf[T]
方法强制转换它们,但是如果不能将类型强制转换为目标类型,则会再次抛出异常。
请注意,即使您可以使用上述技巧使代码工作,该代码也不是您在Scala中所期望的。有一些方法可以使代码更具有类型安全性(例如模式匹配),但是将Json解析为类型安全对象是一个老问题,我敢肯定jackson提供了一种将json解析为案例类。如果不去看看circe,那就可以了。