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