Hi all, which is the more correct/idiomatic way to...
# codingconventions
j
Hi all, which is the more correct/idiomatic way to declare this? 1.
Copy code
private val registry: MutableMap<String, MutableSet<EventListener<*>>> = hashMapOf()
2.
Copy code
private val registry = hashMapOf<String, MutableSet<EventListener<*>>>()
2️⃣ 7
j
2 uses more type inference since it saves us from specifying the MutableMap type
πŸ‘ 1
m
In the first variant you have a
MutableMap
, as you specified, in the second it's a
HashMap
. Slight difference. If you do not really insist on having a hashMap, I'd say, the most idiomatic is 3.
Copy code
private val registry = mutableMapOf<...>()
πŸ‘ 2
t
It's not public API, so I don't think explicit type declaration is necessary. Not much of an idiomatic problem - Both statements have nearly exact same meaning. The only difference between those two is that in #1 you explicitly mention that you don't use HashMap specific methods(which is neglectable as it doesn't have any methods, that are not present in MutableMap interface). Whenever you worry about what's more idiomatic, just try to translate it to English and think what expresses better what you meant to say: 1. There's a private field registry of type MutableMap of event listeners and it's initialized with empty hash map. 2. There's a private field registry initialized with empty hash map of event listeners. So #2 is less verbose and carries at least all what I think that's need to be said.
πŸ‘ 1
j
Thanks everyone! I was leaning towards number 2 as Tomasz said, because it's not a public field, and as Jacob mentioned, for type inference which I felt was more idiomatic. @Manuel Dossinger when should one use hashMapOf() over mutableMapOf()?
h
I like the version of @Manuel Dossinger best. You shouldn't specify the implementation unless you really have to. If at some point in the future a better mutableMap becomes available, your code can take advantage of it. However, if you tie yourself to an implementation, the possible advancements are pretty limited. I checked the source and currently,
mutableMapOf
returns a
LinkedHashMap
as opposed to a regular
HashMap
for
hashMapOf
. So the tradeoff seems to be a little more memory usage, but the insertion order is preserved for iteration.
πŸ‘ 2
j
Thanks @hho much appreciated
t
Doesn't really matter what's the implementation behind
mutableMapOf
as long it's reasonable (O(log n)
get
and
put
). As @hho said unless you require hash map specifically(due to for example resources/time constraints), you should just say "give me mutable map". If for example you would need to preserve insertions order, than you should say "give me `LinkedHashMap`" or even better "give me map, that preserves order", but you should not use
mutableMapOf
despite it's implemented to return
LinkedHashMap
as there's not contract that
mutableMapOf
would return map that preserves order and it would be not clear for the person reading the code, that your code depends on preserving-order contract.
πŸ‘ 1
πŸ™ 1
h
@Tomasz Krakowiak yes there is such a contract: The docs for
mutableMapOf
state that the iteration order is preserved.
πŸ‘ 3
t
I think of coding as expressing my intentions, that's the key to clean code.
πŸ‘Œ 2
@hho Ah, okay. My mistake ^^ Even though, I would prefer explicitly
LinkedHashMap
, as
mutableMapOf
is usually used to express "give me any map" and doesn't really explicitly implies dependency of the order-preserving contract.
m
@hho thanks for jumping in, I was writing an answer and got distracted by a call πŸ˜…
e