1. Overview

List is a pretty commonly used data type in Kotlin. In this tutorial, we’ll explore how to add an element to a Kotlin list.

2. Introduction to the Problem

Compared to Java, apart from ArrayList, Kotlin has a few new types of lists, such as List and MutableList.

If we come from the Java world, these lists may confuse us. Also, when we try to add an element to a list in Kotlin, it’s not always as straightforward as calling the add() method in Java. For example, sometimes, the list.add() line may not compile.

Next, we’ll briefly introduce the three common list types in Kotlin: ArrayList, MutableList and List. Further, we’ll show how to add an element to those lists through examples.

3. ArrayList, MutableList, and List

First of all, let’s take a look at the three different mutability types of collections:

  • Mutable – we can freely change the collection, for example, adding or removing elements.
  • Read-Only – we cannot change the collection’s contents, such as adding or removing elements. However, we’re allowed to modify the underlying data object.
  • Immutable – we cannot change anything about the collection.

Next, let’s look at the three common list types in Kotlin:

  • ArrayList – mutable, similar to Java’s ArrayList
  • MutableList – mutable as well. We often initialize a MutableList using the convenient mutableListOf() function. In this case, we’ll get an ArrayList instance.
  • List – read-only, add() and remove() functions aren’t available

Now that we’ve understood the differences among the three Kotlin list types, let’s see how to add an element to each of them.

For simplicity, we’ll use assertions to verify if the “add” operation works as expected.

Next, let’s see them in action.

4. Adding an Element to an ArrayList

As Kotlin’s ArrayList is almost the same as the one on the Java side, adding an element to a Kotlin ArrayList is not a problem. We can call the add() method to do that:

val myArrayList = ArrayList<String>()
myArrayList.add("Tom Hanks")
assertThat(myArrayList).containsExactly("Tom Hanks")

If we run the test, unsurprisingly, it passes.

It’s worth mentioning that Kotlin supports operator overloading. Moreover, the Kotlin standard library ships with the ‘*+=‘ operator to do “plusAssign*” operation on MutableCollection i.e., adding the elements to the mutable collection.

The += operator can make the code easier to read. For example, we can use ‘*+=*‘ to add a new element to myArrayList:

myArrayList += "Brad Pitt"
assertThat(myArrayList).containsExactly("Tom Hanks", "Brad Pitt")

5. Adding an Element to a MutableList

We’ve learned we can easily initialize a Kotlin MutableList by calling the mutableListOf() method, and the function returns an ArrayList object. Therefore, adding a new element to it is the same as what we did with ArrayList:

val myMutable = mutableListOf("Tom Hanks", "Brad Pitt")
myMutable.add("Tom Cruise")
assertThat(myMutable).containsExactly("Tom Hanks", "Brad Pitt", "Tom Cruise")
myMutable += "Will Smith"
assertThat(myMutable).containsExactly("Tom Hanks", "Brad Pitt", "Tom Cruise", "Will Smith")

As the test above shows, we initialize a MutableList with two elements. Then, we use the same approach to add two elements to the list using the add() method and the += operator.

The test passes if we give it a run.

6. Adding an Element to a Read-Only List

Finally, let’s look at the List type in Kotlin. Since List is read-only, we can’t add an element to it. But let’s create a test to verify if it’s true:

var myList = listOf("Tom Hanks", "Brad Pitt")
myList.add("Tom Cruise")

If we compile the code above, the compiler complains: *“Kotlin: Unresolved reference: add.*” This is expected, as the List interface doesn’t have the add() method.

Next, let’s test the += operator:

val myList = listOf("Tom Hanks", "Brad Pitt")
myList += "Tom Cruise"

As we’ve expected, the code doesn’t compile either. However, the error message is different this time: “*Kotlin: Val cannot be reassigned.*”

Now, let’s take a closer look at this compilation error. First, as the List interface and its super types don’t have the plusAssign() function, here, myList += “Tom Cruise” is the same as myList = myList + “Tom Cruise”. So, it explains how the reassignment happens.

Further, let’s look at the implementation of List‘s ‘*+*‘ (plus operation) operator:

public operator fun <T> Collection<T>.plus(element: T): List<T> {
    val result = ArrayList<T>(size + 1)
    result.addAll(this)
    result.add(element)
    return result
}

As the code above shows, every time we call ‘List + element‘, Kotlin creates a new List containing all the  elements in the original list and the new element. In other words, the ‘+’ operation will return a new object. Next, let’s verify it with a test:

var myList = listOf("Tom Hanks", "Brad Pitt")
val originalList = myList

myList += "Tom Cruise"
assertThat(myList).containsExactly("Tom Hanks", "Brad Pitt", "Tom Cruise")
assertThat(myList).isNotSameAs(originalList)

As we can see, we’ve used the var keyword to declare the myList variable to make it mutable. Also, we want to ensure that after executing myList += “…”, the myList variable will reference a new object.

The test passes if we execute it.

7. Conclusion

In this article, we’ve explored how to add an element to Kotlin’s three common list types.

As always, the complete source code used in the article can be found over on GitHub.