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 PMwithDefaultwasyl
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