如何转换地图的Java地图以在Scala中使用?
我正在开发一个Scala程序,该程序从Java库调用函数,处理结果,并输出CSV 所讨论的Java函数如下所示:如何转换地图的Java地图以在Scala中使用?,java,scala,type-conversion,scala-java-interop,Java,Scala,Type Conversion,Scala Java Interop,我正在开发一个Scala程序,该程序从Java库调用函数,处理结果,并输出CSV 所讨论的Java函数如下所示: Map<String, Map<String, AtomicLong>> getData(); 错误: type mismatch; found:java.util.Map[java...String,java...Map[java...String,java...AtomicLong]] required: scala...
Map<String, Map<String, AtomicLong>> getData();
错误:
type mismatch;
found:java.util.Map[java...String,java...Map[java...String,java...AtomicLong]]
required: scala...Map[String,scala...Map[String,java...AtomicLong]]
(路径名破坏了格式。)
我猜java转换可以成功地转换外部java…映射,但不能转换内部java…映射。我看到了,但我不确定如何写“显-隐转换” 编辑:使用
JavaConverters
和.asScala
方法:
import scala.collection.JavaConverters._
val myScalaMap = myJavaMap.asScala.mapValues(_.asScala)
请注意,您将从中获得可变映射。如果您想要不可变的,可以始终使用.asScala.toMap
原始答案为
JavaConversions
:
简短的回答是:在外部映射上调用.mapValues
,以转换内部映射:
import scala.collection.JavaConversions._
val myScalaMap = myJavaMap.mapValues(_.toMap)
.mapValues
强制将内部映射或外部映射转换为scalamap
和.toMap
强制将内部映射转换为scala(不可变)映射。不可变的部分不是绝对必要的,但无论如何
这很类似于。简短示例:
scala> val a: java.util.Map[String, java.util.Map[String, String]] = new java.util.HashMap[String, java.util.Map[String, String]]
a: java.util.Map[String,java.util.Map[String,String]] = {}
scala> import scala.collection.JavaConversions._
import scala.collection.JavaConversions._
scala> val myScalaMap = a.mapValues(_.toMap)
myScalaMap: scala.collection.Map[String,scala.collection.immutable.Map[String,String]] = Map()
首先,scala中有两个版本的
Maps
和其他主要集合,可变和不可变。默认使用的是不可变版本,您可以通过scala.collection.mutable
包访问可变版本
由于java集合的可变性,将java集合转换为scala可变集合比转换为scala不可变集合要容易得多JavaConversions
无法将java集合转换为scala不可变集合
此外,JavaCollections
无法将内部集合转换为scala类型
我建议您将java映射转换为scala数据结构,如下所示
val javaMap:java.util.HashMap[String,java.util.Map[String,Int]] = new java.util.HashMap()
val scalaMap:Map[String,Map[String,Int]] = javaMap.toMap.map { case (k,v) => k -> v.toMap}
scala.collection.mutable.Map
中定义了.tomap
方法,该方法将可变映射
转换为不可变映射
。和JavaConversions
将java.util.Map
转换为scala immutableMap
我不确定如何着手编写“显-隐转换”
当然,使用JavaConverters
,这个短语暗示了一个自定义隐式
这里是来回的例子:
scala> import scala.collection.JavaConverters._
import scala.collection.JavaConverters._
scala> import java.util.concurrent.atomic.AtomicLong
import java.util.concurrent.atomic.AtomicLong
scala> val m = Map("a" -> Map("b" -> new AtomicLong(7L)))
m: scala.collection.immutable.Map[String,scala.collection.immutable.Map[String,java.util.concurrent.atomic.AtomicLong]] = Map(a -> Map(b -> 7))
scala> val j = m mapValues (_.asJava) asJava
warning: there were 1 feature warning(s); re-run with -feature for details
j: java.util.Map[String,java.util.Map[String,java.util.concurrent.atomic.AtomicLong]] = {a={b=7}}
scala> implicit class mapmap[A,B,C](val v:
| java.util.Map[A,java.util.Map[B,C]]) extends AnyVal {
| def asMapMap: Map[A,Map[B,C]] =
| v.asScala.toMap.mapValues(_.asScala.toMap)
| }
defined class mapmap
scala> j.asMapMap
res0: Map[String,Map[String,java.util.concurrent.atomic.AtomicLong]] = Map(a -> Map(b -> 7))
或者,您可以使用我专门为此编写的库
import com.daodecode.scalaj.collection._
analysisAndCsvStuff(getData.deepAsScala)
就这样。它将所有嵌套的java集合和基元类型转换为scala版本。您还可以使用
deepasscalaimummable
直接转换为不可变的数据结构(当然会有一些复制开销)Huzzah!工作完美。感谢您快速简洁的回复@SamDaniel np:)。请看我的更新,尽管这两个版本都非常有效。我对人们强烈建议使用asScala的链接答案发表了评论。@som snytt谢谢,我对此不确定。令人惊讶的是,JavaConversions
在2.11中没有被弃用。谢谢!Scala的“隐式”一开始对我来说就像伏都教,一个Scala n00b和一个受过ML类型系统艺术训练的人。但我很确定我现在明白它是怎么工作的了。
import com.daodecode.scalaj.collection._
analysisAndCsvStuff(getData.deepAsScala)