给定关联函数,如何合并2个并发映射

时间:2014-11-03 22:01:41

标签: scala collections

合并两个地图的最佳方法是,当两个地图中都存在关键字时,给定一个关联函数。

这是我目前的实施

private def mergeMap[A, B](map1: concurrent.Map[A, B], map2: concurrent.Map[A, B], f: (B, B) => B) : concurrent.Map[A, B] = {
  val keys = map1.keys ++ map2.keys
  val newMap = new TrieMap[A, B]()
  keys.foreach { k =>
    (map1.get(k), map2.get(k)) match {
      case (Some(v1), Some(v2)) => newMap.put(k, f(v1, v2))
      case (Some(v1), None) => newMap.put(k, v1)
      case (None, Some(v2)) => newMap.put(k, v2)
      case _ => // could not happen
    }
  }
  newMap
}

1 个答案:

答案 0 :(得分:2)

'并发地图'是出于某种原因的要求吗?如果没有,你可以轻松使用scalaz

键的关联函数与Semigroup相同:http://eed3si9n.com/learning-scalaz/Functor+Laws.html#Semigroup+Laws

当你有半群可用时,Map变为Monoid,你可以像这样合并它们:

  import scala.collection.concurrent

  import scalaz._
  import Scalaz._

  val map1 = concurrent.TrieMap("a" -> 1, "b" -> 1)
  val map2 = concurrent.TrieMap("b" -> 1, "c" -> 1)

  val merge = map1.toMap |+| map2.toMap

  println(merge)

结果是:

  Map(c -> 1, b -> 2, a -> 1)

如果您不想将它们转换为不可变地图,您可以很容易地为并发地图编写自己的Monoid,但转换几乎是免费的,所以我不明白为什么不使用它