Java 从map[String,Any]类型的Scala映射中提取值,其中Any可以是映射本身

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

我有一个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 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!!!”。