https://kotlinlang.org logo
#announcements
Title
# announcements
t

Travis Griggs

10/25/2019, 3:07 PM
I’m confused by something. HashMap has a filterKeys (among others) method. But they’re defined as Map interface things. It seems I then have to cast the result back to HashMap, e.g. this.modifyRegistry { registry -> registry.filterKeys { oid -> keepOIDs.contains(oid) } as HashMap } I don’t understand why it doesn’t know that registry is a HashMap<PlanID, Plan>. I’ve typed it that way everywhere. But without that
as Hashmap
I get warnings/errors. I feel like I’m missing some piece of the puzzle that it wasn’t obvious/apparent to me to put the as Hashmap there.
g

gian

10/25/2019, 3:11 PM
Usually when you apply this kind of transformations you are creating a new collection and you usually can’t assume that the return type will be the same as the original one
What you can do instead of casting is to use the
toMutableMap
function
The same goes for other types of collection
d

diesieben07

10/25/2019, 3:13 PM
If you want a specific resulting collection, you can use the
xxxTo
methods, such as:
Copy code
val result = myCollection.filterTo(HashMap()) { it > 5 }
💯 3
(That's a stupid example I realize now, because collection and map... but you get the point :D)
t

Travis Griggs

10/25/2019, 3:16 PM
No, .toMutableMap() does not work.
Screen Shot 2019-10-25 at 8.16.02 AM.png
d

diesieben07

10/25/2019, 3:16 PM
Yes,
toMutableMap
will give you a generic
MutableMap
.
refer to my answer above. However it is usually a good idea to code against interfaces (like
Map
,
MutableMap
,
Collection
,
List
, etc.) instead of implementations (like
HashMap
).
👆 2
g

gian

10/25/2019, 3:19 PM
yeah, usually there is no reason in directly exposing implementation types
t

Travis Griggs

10/25/2019, 3:20 PM
At some point though, if I want to create an actual something, I can’t use an interface, can I? e.g. val Registry = HashMap<PlanID, Plan>() If I replace HashMap with Map, I get a no constructors error. As I then write methods around that, it doesn’t like it if I don’t specify HashMap
d

diesieben07

10/25/2019, 3:21 PM
val registry: Map<PlanID, Plan> = HashMap()
💡 1
g

gian

10/25/2019, 3:21 PM
val registry: Map<PlanID, Plan> = mutableMapOf()
d

diesieben07

10/25/2019, 3:22 PM
mutableMapOf
will give you some map implementation, you don't know which.
g

gian

10/25/2019, 3:22 PM
It depends if you actually need the hashmap or not
d

diesieben07

10/25/2019, 3:22 PM
The only guarantee you get is "The returned map preserves the entry iteration order."
Which effectively means you get
LinkedHashMap
g

gian

10/25/2019, 3:23 PM
yeah, but it depends on the requirements
maybe you don’t even need a
MutableMap
t

Travis Griggs

10/25/2019, 3:25 PM
I need a MutableMap in this case (I’m using [] and remove on it). But I could change those. But the the lightbulb is the declaring it as an interface, but creating it with a concrete type. Sort of a duh actually.
Allthough ironically, my original question method still complains because the registry in the original closure now passes a MutableMap, but the filterKeys returns a Map. So I’d have to do the toMutableMap anyway. Took me a few minutes, but I think I get the missing piece now. thanks