dimsuz
04/28/2021, 2:16 PMMutableMap<T, MutableList<R>>
is there a one liner to put an R
into the existing list OR create a list with a single R
, something like
// when map is {}
map.magicOp("one", 3) // → { one: [3] }
map.magicOp("one", 4) // → { one: [3,4] }
wasyl
04/28/2021, 2:18 PMmap.getOrPut
?dimsuz
04/28/2021, 2:20 PMmap.getOrPut("one", { mutableListOf() }).add(3)
map.getOrPut("one", { mutableListOf() }).add(4)
?dimsuz
04/28/2021, 2:20 PMspand
04/28/2021, 2:23 PMgetOrPut
many placesdimsuz
04/28/2021, 2:24 PMwithDefault
wasyl
04/28/2021, 2:25 PMspand
04/28/2021, 2:25 PMephemient
04/28/2021, 3:06 PMmap.getOrPut("one") { mutableListOf() }
ephemient
04/28/2021, 3:07 PMmap.computeIfAbsent("one") { mutableListOf() }
which will be properly atomic on ConcurrentMapFleshgrinder
04/28/2021, 5:33 PMcan move the lambda outside the parens,Or not at allmap.getOrPut("one") { mutableListOf() }
map.getOrPut("one", ::mutableListOf)
🙂ephemient
04/29/2021, 7:52 PM::
doesn't work due to overload resolution, so I tend to use { }
consistently everywhere. that's an opinion of personal style, thoughFleshgrinder
04/30/2021, 5:18 AMephemient
04/30/2021, 5:28 AM::
returns a kotlin.reflect.KFunction
which has some extra methods and interfaces (e.g. ::error.name == "error"
, { error(it) }.name
does not compile)Fleshgrinder
04/30/2021, 6:45 AMfun main() {
mutableMapOf<String, List<String>>().getOrPut("k", ::mutableListOf)
}
Gives:
boolean var0 = false;
Map $this$getOrPut$iv = (Map)(new LinkedHashMap());
Object key$iv = "k";
int $i$f$getOrPut = false;
Object value$iv = $this$getOrPut$iv.get(key$iv);
if (value$iv == null) {
int var4 = false;
boolean var5 = false;
Object answer$iv = (List)(new ArrayList());
$this$getOrPut$iv.put(key$iv, answer$iv);
}
::
does not act as reflection accessor in this case, it's a function reference and compiler instruction.Fleshgrinder
04/30/2021, 6:50 AMpublic fun main() {
mutableMapOf<String, List<String>>().getOrPut("k") { mutableListOf() }
}
In this particular case Kotlin does even produce the same bytecode right away:
boolean var0 = false;
Map $this$getOrPut$iv = (Map)(new LinkedHashMap());
Object key$iv = "k";
int $i$f$getOrPut = false;
Object value$iv = $this$getOrPut$iv.get(key$iv);
if (value$iv == null) {
int var4 = false;
boolean var5 = false;
Object answer$iv = (List)(new ArrayList());
$this$getOrPut$iv.put(key$iv, answer$iv);
}
So, it really is up to personal taste how you write it here, and that's fine. 🙂ephemient
04/30/2021, 6:53 AM.getOrPut()
, but not in the case of .computeIfMissing()
), the bytecode is the same. when it's not inline, it's not quite the sameephemient
04/30/2021, 6:55 AM