使用JavaConversions在java和scala集合之间进行隐式转换

我使用通用函数合并了scala Set of scala Map

 def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] = (Map[A, B]() /: (for (m <- ms; kv  a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) } 

这可以处理存在相同键冲突的情况。 但是,我想在Scala Code中使用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  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 ? 我在这里想念的是什么?

他们说要尝试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) } :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) } ^ :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) } ^ :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) } ^ :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) } :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) } :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) } ^ :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 comprehension产生一组对。

 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)] 

显然,推理无法进行转换,然后找出op类型。

有时打破表达有助于推理,但不是在这里。

 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) } | } 

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()