putIfAbsent用于不可变映射?

时间:2014-05-09 14:39:26

标签: scala collections map concurrency immutability

我经常发现自己编写这样的代码:

import scala.collection.immutable._

var foos = Map.empty[Int, Foo]

def fooOf(n: Int): Foo = {
  foos.get(n) match {
    case Some(foo) => foo
    case None =>
      val foo = new Foo(n)
      foos = foos.updated(n, foo)
      foo
  }
}

使用并发映射,代码看起来更好:

import scala.collection.concurrent._

var foos = TrieMap.empty[Int, Foo]

def fooOf(n: Int): Foo = {
  val foo = new Foo(n)
  foos.putIfAbsent(n, foo) getOrElse foo
}

但我真的想要一个非并发的,不可变的地图。是否有类似putIfAbsent的内容?

(顺便说一句,在并发示例中,只有在确实不存在时才可以创建Foo吗?)

1 个答案:

答案 0 :(得分:2)

如果你对一个可变变量没问题(看起来就像你在两个例子中使用var foos并且只指定了一个不可变的集合),这应该符合你的需要:

var foos = Map.empty[Int, Foo]

def fooOf(n: Int): Foo = {
  foos.getOrElse(n, {
    foos = foos.updated(n, new Foo(n))
    foos(n)
  })
}