I know that withDefault allows you to specify a function that will be applied to a key to produce a default map value, but that function gets called every time you pass an unknown key into the map, even if you pass in the same key -- the values aren't stored in the map.
scala> case class Foo(foo: String) {}
defined class Foo
scala> val m = mutable.OpenHashMap[String, Foo]().withDefault( s => {
| println(s"creating new value for $s")
| Foo(s)
| })
m: scala.collection.mutable.Map[String,Foo] = Map()
scala> m("elvis")
creating value for elvis
res1: Foo = Foo(elvis)
scala> m("elvis")
creating value for elvis
res2: Foo = Foo(elvis)
Now obviously this isn't a big deal for case classes, but if the values are themselves mutable collections, or any other mutable object, it's not very helpful. I'm reduced to using getOrElseUpdate wherever I access the map. Surely there's a more elegant solution?
Or, since in this case the 'default' function is actually the only way I'm going to be generating map values, is there an elegant, Scala-like solution for caching function return values that doesn't involve mutable maps?
ETA: To be clear, I do want to call the function again for each different key. But for a given key, I want to only call the function once, and get the same object back the next time.
mutable.Map.getOrElseUpdate. Also seeMap.computeIfAbsent. - Boris the SpidergetOrElseUpdatebut (as I mentioned in the question) I don't want to have to use it anywhere I access the map. IscomputeIfAbsentavailable in Scala? - David Molesmutable.Mapand override thegetmethod to callgetOrElseUpdatewith a defined function? - Boris the SpidercomputeIfAbsentdocs. And no,getOrElseUpdate()callsget()(see source), so overridingget()wouldn't work. But I could overrideget()to just do more or less whatgetOrElseUpdate()does. I suppose that's my fallback if there's nothing more elegant. - David Moles