So I am new to Kotlin and I am wondering what's the standard way of iterating a Map. I have tried different ways and all of them seem to work, but I don't know if there's one better than the rest or there are some differences that I am not aware of.
var mutMap = mutableMapOf("one" to 1, "two" to 2, "tree" to 3, "four" to 4, "five" to 5)
mutMap.forEach { entry -> println(entry) }
mutMap.iterator().forEach { entry -> println(entry) }
mutMap.entries.forEach { entry -> println(entry) }
mutMap.entries.iterator().forEach { entry -> println(entry) }
for (entry in mutMap) { println(entry) }
for (entry in mutMap.entries) { println(entry) }
for (entry in mutMap.iterator()) { println(entry) }
for (entry in mutMap.entries.iterator()) { println(entry) }
Also, if I wanted to also delete an entry while iterating over them, none of them would work, right?
If you browse through Kotlin's Collections package there is a whoooole lot of stuff you can use, yeah! Lots of different functions that let you drill down into specific pieces of data (like keys or values vs entries, or providing indices) or getting specific behaviour as you process a collection.
The examples you've given are all basically the same thing though. Here's the page for all the
forEachfunctions on the various types of collections:And here's the source code for those (there's a source link under every function's main page, useful to know about! You can see exactly how they work)
So really they're all wrappers for a basic
forloop, which as the documentation says, iterates through anything that provides an iterator. Your examples are all basically the same thing that's happening, just jumping in at various points in the forEach -> basic for loop -> get an iterator process.The only part that's different is when you call
entries, which returns aSetholding the key/valueEntrypairs - so you're iterating over that, rather than theMapitself. But wait, what does happen if you calliterator()on aMap?It uses
entriesitself! So yeah they're all the same thingReally I think it comes down to this
iterator()on anything unless you know you need one for some reason, like you're going to be callinghasNext()on it or whateverforEachfits with Kotlin's more declarative style, can be chained, and automatically passes in variables instead of you having to declare themforloop is more readable for what you're doing though, especially if you're modifying some kind ofresultvariable (which is more comparable to afoldthan aforEachbut anywayentrieson aMapmeans you're being explicit about what you're working with when you chain aforEachonto it, similar to how you can specifykeysorvaluesand only work with those. It's the same as just callingforEachon the map itself, but it's clearer