Java 从map[String,Any]类型的Scala映射中提取值,其中Any可以是映射本身
我有一个scala方法,如:Java 从map[String,Any]类型的Scala映射中提取值,其中Any可以是映射本身,java,scala,map,jvm,Java,Scala,Map,Jvm,我有一个scala方法,如: import collection.JavaConversions._ def foo(message: Map[String, Any]) { // message is implicitly converted to Java format someJavaApi.method1(message) message.get("mapField") match { case Some(mapField) => val
import collection.JavaConversions._
def foo(message: Map[String, Any]) {
// message is implicitly converted to Java format
someJavaApi.method1(message)
message.get("mapField") match {
case Some(mapField) =>
val stringValue = mapField.asInstanceOf[Map[String, String]].get("internalField")
otherJavaApi.method(stringValue)
case None => /* do something */
}
}
其中,message是一个具有如下结构的映射:
Map(
"field" -> "value",
"mapField"-> Map("internalField"->"someValue")
)
从上面的代码中可以明显看出,我对从“mapField”字典对象的“internalField”中提取“someValue”感兴趣
但我在运行时不断遇到一个错误,如:
scala.collection.JavaConversions$JMapWrapper cannot be cast to scala.collection.immutable.Map
我觉得这是由于调用第一个java库API时从scala隐式转换为java集合,但我不确定这一点,我想就如何改进从“mapField”中提取字符串值“someValue”提出建议,以更具功能性或更具伸缩性的方式,并避免异常
我正在使用scala 2.9.2版本。我试图从您的代码中创建一个工作示例:
import collection.JavaConversions._
object Test extends App {
object someJavaApi {
def method1(message: java.util.Map[_, _]) { }
}
object otherJavaApi {
def method(s: String) { }
}
def foo(message: Map[String, Any]) {
// message is implicitly converted to Java format
someJavaApi.method1(message)
message.get("mapField") match {
case Some(mapField) =>
val stringValue = mapField.asInstanceOf[Map[String, String]]("internalField")
otherJavaApi.method(stringValue)
case None => /* do something */
}
}
val message = Map(
"field" -> "value",
"mapField" -> Map("internalField" -> "someValue")
)
foo(message)
}
它运行无误
但是我不知道如果不编译代码就可以回答这个问题。Java映射是可变的,因此它们的Scala包装器是可变的.Map,而不是不变的.Map
scala> Map("field" -> "value","mapField"-> Map("internalField"->"someValue"))
res0: scala.collection.immutable.Map[String,Object] = Map(field -> value, mapField -> Map(internalField -> someValue))
scala> import collection.JavaConverters._
import collection.JavaConverters._
scala> res0.mapValues { case m: Map[_,_] => m.asJava case x => x }
res2: scala.collection.immutable.Map[String,Object] = Map(field -> value, mapField -> {internalField=someValue})
scala> res0.asJava
res3: java.util.Map[String,Object] = {field=value, mapField=Map(internalField -> someValue)}
scala> .asScala
res4: scala.collection.mutable.Map[String,Object] = Map(field -> value, mapField -> Map(internalField -> someValue))
scala> .foreach { case (k, v: collection.Map[_,_]) => println(v.toList) case _ => }
List((internalField,someValue))
安全方面的一些帮助:
scala> :edit res0
+Map("field" -> Left("value"),"mapField"-> Right(Map("internalField"->"someValue")))
res6: scala.collection.immutable.Map[String,Product with Serializable with scala.util.Either[String,scala.collection.immutable.Map[String,String]]] = Map(field -> Left(value), mapField -> Right(Map(internalField -> someValue)))
scala> .mapValues { case Left(s) => s.length case Right(m) => m.values.map(_.length).sum }
res7: scala.collection.immutable.Map[String,Int] = Map(field -> 5, mapField -> 9)
很难说你在这里问什么-如果你能提供可编译的示例代码,那会有所帮助。只需对
映射[String,Any]
说“no!!!”。