Kotlin has the two data structures you meet in heaven: lists and maps.
Working with these collection types in Kotlin also allows its type inference to really shine compared to Java.
Kotlin supports lists: the most general and basic ordered data collection. Lists structure data by putting items in order.
The easiest way to create a list is to use the
listOf operator, which converts
a variable number of arguments into a list.
listOf determines the type of the list by examining its arguments.
Lists know how long they are, support square bracket indexing, and can be used
in the Kotlin
However, one immediate gotcha: Kotlin lists are immutable.
The first error message here is odd, but the second and third make more sense.
Note that if you are programming in an IDE, it will warn you that the
method doesn’t exist, which will strike you as odd.
Until you remember that you wanted a mutable list.
If we want to create a mutable list we need to use
Here is another place where Kotlin bends toward immutability.
listOf could have produced a mutable list and been paired with
immutableListOf for producing immutable lists.
But Kotlin encourages us to transform—rather than mutate—our data.
We’ll see some extremely elegant ways to transform collections in the next
But when you need to mutate a list,
toMutableList will transform a list into
an immutable list, while
toList will transform a mutable list into an
Finally, it’s worth mentioning that many other kinds of ordered data structures in Kotlin have helper methods to turn them into lists. Here’s one example:
Let’s stop here to identify an important distinction between variable mutability
var) and list mutability (
Lacking type inference, Java’s lists introduce so much syntax clutter that they can be hard to introduce to begginers. But, of course, Java does have multiple list implementations that work similarly to Kotlin’s built-in lists:
A single line, but a rather fearsome blizzard of syntax, including needed to
Integer twice, once on both sides of the expression.
Python is much cleaner, of course, but without type safety:
list = [1, 2, 4]
Kotlin also has built-in support for maps: the most basic associative data collection. Maps structure data by establishing mappings between keys that can be used to retrieve values.
This map maps keys that are strings to values that are strings. Note how we initialize the map with key-value pairs use the "key to value" syntax.
Happily, maps also support bracket notation to both access and modify key-value mappings. Syntatically this brings them more in line with Python’s dictionarys, except with type safety.
Just like lists, Kotlin includes both immutable (
mapOf) and immutable
mutableMapOf) maps, and operators to transform one to the other:
We can iterate through maps in several ways.
.keys property allows us to access a list of all the maps keys:
But, of course, there is a more Kotliniomatic way to do this:
But you should rarely access a map using a
We’re about to get to the right way to do this, so sit tight!
The list and map builder functions
mapOf, and the like do a nice job
of inferring the types of your list or map.
But what if you want to create an empty list (mutable, of course)?
In that case, just like when we declared but didn’t initialize a variable, we
need to provide Kotlin with the type that the collection will eventually
Maps work similarly, except that we need to provide both the key and value type:
Even when Kotlin’s type inference works, you may want to specify your types to catch common mistakes. Consider this example:
The problem here is that
mutableMapOf inferred the type of the map to be
<Int, Object> so that both 3 and "three" could be used as values.
So when we extract a value from the map we get an
Object, not an
we can add to 4.
Including a type when declaring the map would have helped catch this mistake: