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 SpidergetOrElseUpdate
but (as I mentioned in the question) I don't want to have to use it anywhere I access the map. IscomputeIfAbsent
available in Scala? – David Molesmutable.Map
and override theget
method to callgetOrElseUpdate
with a defined function? – Boris the SpidercomputeIfAbsent
docs. 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