使用immutable.ListMap代替mutable.LinkedHashMap

时间:2019-04-25 09:08:14

标签: scala functional-programming

我想尽可能地使用不变的数据结构。 在我们的代码库中,非常普遍的情况是使用 mutable.LinkedHashMap 。我想在所有非性能关键代码中将其替换为 immutable.ListMap

我们的代码具有的常规格式

  1. mutable.LinkedHashMap初始化
  2. 循环条件
  3. 基于LinkedHashMap中的某些条件添加元素
  4. 循环后,返回LinkedHashMap

示例代码:

def dummyFunction(): mutable.LinkedHashMap[Int, String] = {
    val tmpListMap: mutable.LinkedHashMap[Int, String] = mutable.LinkedHashMap()
    for (i <- 1 to 10) {
        if (i%2 ==0) tmpListMap += (i -> "even")
        else tmpListMap += (i -> "odd")
    }
    tmpListMap
}

我想在所有这些地方使用ListMap。我不想再次循环tmpListMap来创建ListMap。

Scala版本:2.11

1 个答案:

答案 0 :(得分:4)

您不知道如何返回不可变的地图,因为创建后无法对其进行修改?那是问题吗? 很多方法。例如:

(1 to 10).map { 
    case x if x%2 == 0 => (x -> "even")
    case x => (x -> "odd")
 }.toMap

以上代码返回常规的Map,而不是ListMap。我不确定为什么要使用后者,但是,如果您出于某种原因这样做,则涉及更多:

 val tuples = (1 to 10).map { 
    case x if x%2 == 0 => (x -> "even")
    case x => (x -> "odd")
 }
 ListMap(tuples:_*)

是的,您也可以从理解中屈服(我不确定在这种情况下为什么要这么做),像这样:

val tuples = for {
  x <- 1 to 10 
  kind = if (x %2 == 0) "even" else "odd"
} yield (x -> kind) 

这与上面的map调用具有相同的作用。

您也可以从ListMap开始,以免在结尾处进行转换:

 ListMap((1 to 10).map(_ -> ""):_*).map { 
   case (k, _) if k%2 == 0 => k -> "even"
   case (k, _) => k -> "odd"
 }

或者只是:

 ListMap(
    (1 to 10).map {
       case x if x%2 == 0 => x -> "even"
       case x => x -> "odd"
     }:_*
 )

还有.foldLeft,可让您以最类似于当前含义的方式来编写它,即它逐渐积累了地图中的更改,而不是在最后进行一次转换。 ..不确定为什么会这样,但这是效率最低的方法:

 (1 to 10).foldLeft(ListMap.empty[Int, String]) { 
    case (x, map) if x%2 == 0 => map.updated(x, "even")
    case (x, map) => map.updated(x, "odd")
 }