Java嵌套Map到Scala嵌套序列

时间:2012-10-03 16:07:26

标签: java scala playframework-2.0

我是Scala的新手,我们的项目将Java和Scala代码混合在一起(使用Play Framework)。我正在尝试编写一个可以采用嵌套Java Map的Scala方法,例如:

LinkedHashMap<String, LinkedHashMap<String, String>> groupingA = new LinkedHashMap<String, LinkedHashMap<String,String>>();

将Java对象传递给可以循环遍历的Scala函数。我有以下scala对象定义来尝试并支持上面的Java嵌套映射:

Seq[(String, Seq[(String,String)])]

Java文件和Scala文件都可以单独编译,但是当我的java对象尝试创建我的scala类的新实例并传入嵌套映射时,我收到编译器错误,其中包含以下详细信息:

[error]  ..... overloaded method value apply with alternatives:
[error]   (options: java.util.List[String])scala.collection.mutable.Buffer[(String, String)] <and>
[error]   (options: scala.collection.immutable.List[String])List[(String, String)] <and>
[error]   (options: java.util.Map[String,String])Seq[(String, String)] <and>
[error]   (options: scala.collection.immutable.Map[String,String])Seq[(String, String)] <and>
[error]   (options: (String, String)*)Seq[(String, String)]
[error]  cannot be applied to (java.util.LinkedHashMap[java.lang.String,java.util.LinkedHashMap[java.lang.String,java.lang.String]])

这里有关于如何将嵌套的Java LinkedHashMap(如上所述)传递到Scala文件中的任何想法,我可以在一个嵌套集合中进行一般迭代?我正在尝试编写这个通用名称,以便它可以用于嵌套的Scala集合,以防我们切换到在Scala而不是Java中编写我们的游戏框架控制器。

2 个答案:

答案 0 :(得分:1)

试试这个:

import scala.collections.JavaConversions.mapAsScalaMap

val lhm: LinkedHashMap[String, LinkedHashMap[String, String]] = getLHM()
val scalaMap = mapAsScalaMap(lhm).mapValues(mapAsScalaMap(_).toSeq).toSeq

我对此进行了测试,得到了Seq[String, Seq[(String, String)]]

类型的结果

(转换将包装原始Java对象,而不是实际创建带有值副本的Scala对象。因此,不需要转换为Seq,您可以将其保留为Map,迭代顺序将是同样的。)

我猜,你在处理查询参数吗?

答案 1 :(得分:1)

Seq是Scala Collections层次结构中定义的基本特征。虽然java和scala提供字节码兼容性,但scala定义了许多自己的类型,包括它自己的集合库。这里的问题是如果你想编写惯用的scala,你需要将你的java数据转换为scala数据。我看到它的方式你有几个选择。

  • 您可以使用Richard的解决方案,并在scala代码中将java类型转换为scala类型。我认为这很难看,因为它假设你的输入总是来自java土地。

  • 您可以编写漂亮,完美的scala处理程序并提供一个提供丑陋的Java转换行为的伴随对象。这会将您的scala实现从java详细信息中解开。

  • 或者你可以写一个隐含的def,就像下面那个将它归结为你内心的内容。

import java.util.LinkedHashMap
import scala.collection.JavaConversions.mapAsScalaMap

object App{
  implicit def wrapLhm[K,V,G](i:LinkedHashMap[K,LinkedHashMap[G,V]]):LHMWrapper[K,V,G] = new LHMWrapper[K,V,G](i)

  def main(args: Array[String]){
    println("Hello World!")
    val lhm = new LinkedHashMap[String, LinkedHashMap[String,String]]()
    val inner = new LinkedHashMap[String,String]()
    inner.put("one", "one")
    lhm.put("outer",inner);
    val s = lhm.getSeq()
    println(s.toString())
  }
  class LHMWrapper[K,V,G](value: LinkedHashMap[K,LinkedHashMap[G,V]]){
    def getSeq():Seq[ (K, Seq[(G,V)])] = mapAsScalaMap(value).mapValues(mapAsScalaMap(_).toSeq).toSeq
  }
}