获取对不可变Map的引用



我在一个集合上进行并行运算,以计算列表中相同项目值的数量。这种情况下的列表是uniqueSetOfLinks:

for (iListVal <- uniqueSetOfLinks.par) {
  try {
      val num : Int = listOfLinks.count(_.equalsIgnoreCase(iListVal))
      linkTotals + iListVal -> num
  }
  catch {
  case e : Exception => {
   e.printStackTrace() 
  }
  }
}

linkTotals是一个不可变的Map。为了获得链接总数的引用,我需要更新linkTotals以使其不可变吗?

然后我可以做一些类似的事情:

linkTotals.put(iListVal, num)

你不能更新不可变集合,你所能做的就是将不可变集合与addition元素结合起来,得到新的不可变集合

val newLinkTotals = linkTotals + (iListVal -> num)

在收集的情况下,你可以创建新的配对集合,然后将所有配对添加到地图中:

val optPairs =
  for (iListVal <- uniqueSetOfLinks.par)
    yield
      try {
        val num : Int = listOfLinks.count(_.equalsIgnoreCase(iListVal))
        Some(iListVal -> num)
      }
      catch {
        case e : Exception =>  e.printStackTrace()
        None
      }

val newLinkTotals = linkTotals ++ optPairs.flatten // for non-empty initial map
val map = optPairs.flatten.toMap // in case there is no initial map

请注意,您使用的是并行集合(.par),因此不应该使用可变状态,如linkTotals += iListVal -> num

@senia答案的可能变体(去掉显式flatten):

val optPairs =
  (for {
    iListVal <- uniqueSetOfLinks.par
    count <- {
      try
        Some(listOfLinks.count(_.equalsIgnoreCase(iListVal)))
      catch {
        case e: Exception =>
          e.printStackTrace()
          None
      }
    }
  } yield iListVal -> count) toMap

我认为您需要某种形式的MapReduce才能进行并行的项目数量估计。

在您的问题中,您已经拥有所有唯一的链接。映射的部分中间结果只是一对。而"reduce"就是toMap。因此,您可以简单地将链接映射到对(link->count),然后最终构建一个映射:

def count(iListVal:String) = listOfLinks.count(_.equalsIgnoreCase(iListVal))
val listOfPairs = uniqueSetOfLinks.par.map(iListVal => Try( (iListVal, count(iListVal)) ))

("地图"操作是标准地图)

然后删除异常:

val clearListOfPairs = listOfPairs.flatMap(_.toOption)

然后简单地将其转换为地图("reduce"):

val linkTotals = clearListOfPairs.toMap

(如果需要检查异常,请使用Try.failure)

最新更新