如何从 java.util.Map 转换为 Scala Map
Java API 返回 java.util.Map
;。 我想将其放入 Map[String,Boolean]
所以想象一下:
var scalaMap : Map[String,Boolean] = Map.empty
val javaMap = new JavaClass().map() // Returns java.util.Map<java.lang.String,java.lang.Boolean>
你不能做 Map.empty ++ javaMap
,因为 ++ 方法不了解 Java 地图。 我尝试过:
scalaMap = Map.empty ++ new collection.jcl.MapWrapper[String,Boolean] {
override def underlying = javaMap
}
和:
scalaMap = Map.empty ++ new collection.jcl.MapWrapper[java.lang.String,java.lang.Boolean] {
override def underlying = javaMap
}
这些都无法编译,因为泛型 - java.lang.String
与 scala String 不同。
除了手动复制地图之外,有没有一种好方法可以做到这一点?
编辑:谢谢,所有好的答案,我从他们身上学到了很多东西。 然而,我犯了一个错误,在这里发布了一个比我实际遇到的问题更简单的问题。 所以,如果你允许的话,我会概括这个问题 - API 实际返回的是
java.util.Map<java.lang.String, java.util.Map<SomeJavaEnum,java.lang.String>>
我需要将其移至 Map[String, Map[SomeJavaEnum,String]]
它可能看起来不太复杂,但它增加了额外级别的类型擦除,我发现将其移动到 Scala 映射的唯一方法是深度复制它(使用您在下面建议的一些技术)。 有人有任何提示吗? 我通过为我的确切类型定义隐式转换来解决我的问题,所以至少丑陋隐藏在它自己的特征中,但仍然感觉有点笨拙的深度复制很多。
A Java API returns a java.util.Map<java.lang.String,java.lang.Boolean>
;. I would like to put that into a Map[String,Boolean]
So imagine we have:
var scalaMap : Map[String,Boolean] = Map.empty
val javaMap = new JavaClass().map() // Returns java.util.Map<java.lang.String,java.lang.Boolean>
You can't do Map.empty ++ javaMap
, because the ++ method does not know about Java maps. I tried:
scalaMap = Map.empty ++ new collection.jcl.MapWrapper[String,Boolean] {
override def underlying = javaMap
}
and:
scalaMap = Map.empty ++ new collection.jcl.MapWrapper[java.lang.String,java.lang.Boolean] {
override def underlying = javaMap
}
These both fail to compile, because of the generics - java.lang.String
is not the same as a scala String.
Is there a good way of doing this, short of copying the map manually?
EDIT: Thanks, all good answers, I learned a lot from all of them. However, I made a mistake by posting a simpler problem here than the one I actually have. So, if you allow me, I'll generalise the question - What the API actually returns is
java.util.Map<java.lang.String, java.util.Map<SomeJavaEnum,java.lang.String>>
And I need to move this to Map[String, Map[SomeJavaEnum,String]]
It probably does not seem like too much of a complication, but it adds an extra level of type erasure, and the only way I found of moving this to a Scala map was deep-copying it (using some of the techniques you suggested below). Anyone any hints? I kind of solved my problem by defining an implicit conversion for my exact types, so at least the ugliness is hidden in its own trait, but still feels a bit clumsy deep copying the lot.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
至少在 Scala 2.9.2 中,集合转换有一种更简单的方法:导入“import collection.JavaConversions._”并使用“toMap”。
示例:
它可以与 String 到 Boolean 的 java.util.map 配合使用。
At least with Scala 2.9.2 there's an easier way with the collections conversions: import "import collection.JavaConversions._" and use "toMap".
Example:
It works fine with a java.util.map of String to Boolean.
Scala
String
是java.lang.String
但是 ScalaBoolean
不是 一个java.lang.Boolean
。 因此,以下工作有效:但您的问题仍然是
Boolean
差异的问题。 您必须将 Java 映射“折叠”到 scala 映射中:使用 ScalaBoolean
类型重试:然后
mm
是一个包含原始内容的 scala 映射scala 映射加上 Java 映射中的内容A Scala
String
is ajava.lang.String
but a ScalaBoolean
is not ajava.lang.Boolean
. Hence the following works:But your problem is still the issue with the
Boolean
difference. You'll have to "fold" the Java map into the scala one: try again using the ScalaBoolean
type:Then
mm
is a scala map containing the contents of the original scala map plus what was in the Java mapuseJavaMap.scala
test/test.java
命令行
useJavaMap.scala
test/test.java
Commandline
我想我有一个部分答案......
如果你将java映射转换为具有java类型的scala映射。 然后,您可以将其映射到 scala 类型的 scala 映射:
该计划的缺陷是 scalaMap 的类型是 Iterable[(java.lang.String, Boolean)] 而不是映射。 我感觉很接近,有比我聪明的人可以修改最后一个语句来使这个工作成功吗?!
I think I have a partial answer...
If you convert the java map to a scala map with the java types. You can then map it to a scala map of scala types:
The flaw in this plan is that the type of
scalaMap
is Iterable[(java.lang.String, Boolean)] not a map. I feel so close, can someone cleverer than me fix the last statement to make this work?!