使用 JavaConversions 在 java 和 scala 集合之间进行隐式转换
Implicit conversion between java and scala collections using JavaConversions
我使用通用函数合并了一个 Set
的 Map
个 Scala
def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] =
(Map[A, B]() /: (for (m <- ms; kv <- m) yield kv))
{
(a, kv) =>
a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv)
}
这可以处理相同键发生冲突的情况。但是,我想在 Scala 代码中使用 Java 集合来完成。我研究了一下,发现 JavaConversions
。我导入它并写了这个
def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] =
(new util.HashMap[A, B] /: (for (m <- ms; kv <- m) yield kv))
{
case (a, kv) =>
a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv)
}
但是,它说类型不匹配
Error:(67, 11) type mismatch;
found : scala.collection.mutable.Map[A,B]
required: java.util.HashMap[A,B]
a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv)
^
不就是JavaConversions
用来隐式转换util.HashMap
到mutable.Map
吗?我在这里错过了什么?
JavaConverter
会做你想做的事吗?
scala> import scala.collection.JavaConverters._
import scala.collection.JavaConverters._
scala> val x = (new java.util.HashMap[Int,Int]).asScala
x: scala.collection.mutable.Map[Int,Int] = Map()
他们说尝试 JavaConverters,因为 JavaConversions 已被弃用。
scala> import collection.JavaConverters._
import collection.JavaConverters._
scala> def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] =
| (new java.util.HashMap[A, B] /: (for (m <- ms; kv <- m) yield kv)) {
| case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
<console>:16: error: value contains is not a member of java.util.HashMap[A,B]
case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
^
<console>:16: error: java.util.HashMap[A,B] does not take parameters
case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
^
<console>:16: error: type mismatch;
found : (A, B)
required: String
case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
^
<console>:15: error: type mismatch;
found : java.util.HashMap[A,B]
required: Map[A,B]
(new java.util.HashMap[A, B] /: (for (m <- ms; kv <- m) yield kv)) {
^
scala> def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] =
| (new java.util.HashMap[A, B].asScala /: (for (m <- ms; kv <- m) yield kv)) {
| case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
<console>:15: error: type mismatch;
found : scala.collection.mutable.Map[A,B]
required: scala.collection.immutable.Map[A,B]
(new java.util.HashMap[A, B].asScala /: (for (m <- ms; kv <- m) yield kv)) {
^
scala> def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] =
| (new java.util.HashMap[A, B].asScala.toMap /: (for (m <- ms; kv <- m) yield kv)) {
| case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
mergeMaps: [A, B](ms: Set[Map[A,B]])(f: (B, B) => B)Map[A,B]
也许是为了说明它被弃用的原因:
scala> def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] =
| (new java.util.HashMap[A, B] /: (for (m <- ms; kv <- m) yield kv)) {
| case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
<console>:19: error: type mismatch;
found : scala.collection.mutable.Map[A,B]
required: java.util.HashMap[A,B]
case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
^
<console>:18: error: type mismatch;
found : java.util.HashMap[A,B]
required: Map[A,B]
(new java.util.HashMap[A, B] /: (for (m <- ms; kv <- m) yield kv)) {
^
注意到 for 理解产生了一组对。
scala> def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B) = for (m <- ms; kv <- m) yield kv
mergeMaps: [A, B](ms: Set[Map[A,B]])(f: (B, B) => B)scala.collection.immutable.Set[(A, B)]
显然推理无法既进行转换又找出操作类型。
有时分解表达式有助于推理,但这里不是。
scala> def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] = {
| val ss = for (m <- ms; kv <- m) yield kv
| (new java.util.HashMap[A, B] /: ss) {
| case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
| }
我使用通用函数合并了一个 Set
的 Map
个 Scala
def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] =
(Map[A, B]() /: (for (m <- ms; kv <- m) yield kv))
{
(a, kv) =>
a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv)
}
这可以处理相同键发生冲突的情况。但是,我想在 Scala 代码中使用 Java 集合来完成。我研究了一下,发现 JavaConversions
。我导入它并写了这个
def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] =
(new util.HashMap[A, B] /: (for (m <- ms; kv <- m) yield kv))
{
case (a, kv) =>
a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv)
}
但是,它说类型不匹配
Error:(67, 11) type mismatch;
found : scala.collection.mutable.Map[A,B]
required: java.util.HashMap[A,B]
a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv)
^
不就是JavaConversions
用来隐式转换util.HashMap
到mutable.Map
吗?我在这里错过了什么?
JavaConverter
会做你想做的事吗?
scala> import scala.collection.JavaConverters._
import scala.collection.JavaConverters._
scala> val x = (new java.util.HashMap[Int,Int]).asScala
x: scala.collection.mutable.Map[Int,Int] = Map()
他们说尝试 JavaConverters,因为 JavaConversions 已被弃用。
scala> import collection.JavaConverters._
import collection.JavaConverters._
scala> def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] =
| (new java.util.HashMap[A, B] /: (for (m <- ms; kv <- m) yield kv)) {
| case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
<console>:16: error: value contains is not a member of java.util.HashMap[A,B]
case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
^
<console>:16: error: java.util.HashMap[A,B] does not take parameters
case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
^
<console>:16: error: type mismatch;
found : (A, B)
required: String
case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
^
<console>:15: error: type mismatch;
found : java.util.HashMap[A,B]
required: Map[A,B]
(new java.util.HashMap[A, B] /: (for (m <- ms; kv <- m) yield kv)) {
^
scala> def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] =
| (new java.util.HashMap[A, B].asScala /: (for (m <- ms; kv <- m) yield kv)) {
| case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
<console>:15: error: type mismatch;
found : scala.collection.mutable.Map[A,B]
required: scala.collection.immutable.Map[A,B]
(new java.util.HashMap[A, B].asScala /: (for (m <- ms; kv <- m) yield kv)) {
^
scala> def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] =
| (new java.util.HashMap[A, B].asScala.toMap /: (for (m <- ms; kv <- m) yield kv)) {
| case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
mergeMaps: [A, B](ms: Set[Map[A,B]])(f: (B, B) => B)Map[A,B]
也许是为了说明它被弃用的原因:
scala> def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] =
| (new java.util.HashMap[A, B] /: (for (m <- ms; kv <- m) yield kv)) {
| case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
<console>:19: error: type mismatch;
found : scala.collection.mutable.Map[A,B]
required: java.util.HashMap[A,B]
case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
^
<console>:18: error: type mismatch;
found : java.util.HashMap[A,B]
required: Map[A,B]
(new java.util.HashMap[A, B] /: (for (m <- ms; kv <- m) yield kv)) {
^
注意到 for 理解产生了一组对。
scala> def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B) = for (m <- ms; kv <- m) yield kv
mergeMaps: [A, B](ms: Set[Map[A,B]])(f: (B, B) => B)scala.collection.immutable.Set[(A, B)]
显然推理无法既进行转换又找出操作类型。
有时分解表达式有助于推理,但这里不是。
scala> def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] = {
| val ss = for (m <- ms; kv <- m) yield kv
| (new java.util.HashMap[A, B] /: ss) {
| case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
| }