typedmap icon indicating copy to clipboard operation
typedmap copied to clipboard

Support Map-like "computeIfAbsent" method

Open bitspittle opened this issue 3 years ago • 1 comments
trafficstars

For reference: https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#computeIfAbsent-K-java.util.function.Function-

Side note: there are a bunch of other methods in the Map class, such as computeIfPresent, merge, putIfAbsent, etc., that seem to be missing, but I'm not sure if every method carries over cleanly to the TypedMap concept. Still, it may be worth auditing all the methods in the Map API to double-check if they can be migrated to TypedMap.

computeIfAbsent is really useful and I use it all the time. It's great for lazy initialization.

For example, maybe I want to record a set of seen ID values, but most people may not use the feature that registers them.

Right now, if I understand it, you'd have to do something like:

sess += mutableSetOf<String>()

... later ...
fun registerId(id: String) {
   val ids = sess.get<MutableSet<String>>()
   require(!ids.containsKey(id)) { "Duplicate id registered: $id" }
   ids.add(id)
}

OR

object IdKey : TypedKey<MutableSet<String>>()
sess[IdKey] = mutableSetOf<String>()

... later ...
fun registerId(id: String) {
   val ids = sess[IdKey]
   ...
}

With computeIfAbsent, I can use this pattern, which is both fewer lines and only instantiates the set if I need it:

fun registerId(id: String) {
   val ids = sess.computeIfAbsent { mutableSetOf<String>() }
   require(!ids.containsKey(id)) { "Duplicate id registered: $id" }
   ids.add(id)
}

OR

... later ...
fun registerId(id: String) {
   val ids = sess.computeIfAbsent(IdKey) { mutableSetOf<String>() }
   ...
}

If there's a way to do this with the existing APIs that I missed, my apologies!

bitspittle avatar Feb 15 '22 00:02 bitspittle

Thank you for suggestion.

Initially, I planned to make TypedMap more similar to Map, however, it turned out there aren't too many functions that could be used with TypedMap due to its specific type handling. computeIfAbsent() makes perfect sense for TypedMap :-) Although, I would probably stick to Kotlin's getOrPut(), getOrElse(), getOrDefaulr() naming scheme.

broo2s avatar Feb 20 '22 16:02 broo2s