我使用通用函数合并了scala Set的scalaMap
Set
Map
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 Code中的Java集合来实现。我研究了一下,发现了JavaConversions。我导入并编写了这个
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?我在这里想念什么?
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) } <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) } | }