Start learning free

LESSON 94 OF 348 · ARRAYS I

Updating List Elements in Kotlin: The Index Operator

Lesson Read the full explanation

The entries of lists are mutable and can be changed freely, using indices and the index operator []:

The index operator [] takes an index and a value and changes the element placed at that index with the argument value:

val numbers = mutableListOf(50, 40, 30)

numbers[0] = 15
numbers[2] = -1

// numbers is now [15, 40, -1]

Assignment
Follow the Coding Tutorial and let's play with some arrays.


Hint
Look at the examples above if you get stuck.


STEP 1 OF 2
    Ctrl + Enter to check

    KOTLIN · ARRAYS I

    Updating Elements in Kotlin, explained

    Replacing an element

    The elements of a MutableList can be changed. Use the index operator [] on the left of an assignment, with the index in the brackets and the new value on the right. Kotlin turns that into a call to the list's set method, so numbers[0] = 15 and numbers.set(0, 15) do the same thing.

    val numbers = mutableListOf(50, 40, 30)
    numbers[0] = 15
    numbers[2] = -1
    println(numbers)
    
    [15, 40, -1]
    

    Only the elements at indices 0 and 2 changed. The size is still 3, and the element at index 1 is still 40.

    Read-only lists

    This only works on a mutable list. A list made with listOf is read-only, and listOf(1, 2)[0] = 5 doesn't compile: the compiler reports that there is no set operator method providing array access. That is why the lesson builds its lists with mutableListOf.

    Using the old value

    To change an element based on its current value, read it, compute the new value and store it in the same place:

    val scores = mutableListOf(10, 20, 30)
    scores[1] = scores[1] + 5
    println(scores)
    
    [10, 25, 30]
    

    The right side is evaluated first, using the old value 20, and the result 25 is then stored at index 1. Kotlin also accepts the shorter scores[1] += 5, which means the same.

    Replacing versus adding

    Assignment by index and add do different jobs. Assignment replaces an element that is already there: the index must be valid, and the size stays the same. add puts a new element at the end and makes the list one longer. Mixing them up is a common beginner error, such as writing ages[4] = 7 on a four-item list when ages.add(7) was meant.

    Why val still works

    Changing an element isn't the same as reassigning the variable. The statement fruits[0] = "apple" changes what the list holds, while fruits = mutableListOf() would try to point the variable somewhere else, which a val forbids. That is why a val list can be updated freely.

    The exercise

    The starter code:

    val fruits = mutableListOf("mango", "kiwi", "grapefruit")
    val ages = mutableListOf(14, 32, 50, 21)
    
    1. Replace the first fruit. Assign "apple" to index 0. The variable fruits is a val, but that only stops it from being pointed at another list, so changing an element is fine.
    2. Add 5 to the second age. The second item is at index 1. Assign ages[1] + 5 back to ages[1], turning 32 into 37.
    val fruits = mutableListOf("mango", "kiwi", "grapefruit")
    val ages = mutableListOf(14, 32, 50, 21)
    
    fruits[0] = "apple"
    ages[1] = ages[1] + 5
    

    Nothing is printed. With println(fruits) and println(ages) added, the output is [apple, kiwi, grapefruit] and [14, 37, 50, 21].

    Compound forms

    The shorthand operators work on list elements as well: ages[1] += 5 reads the element, adds 5 and stores the result at the same index, and -=, *= and /= follow the same pattern. The long form in the exercise, ages[1] = ages[1] + 5, and the short form give the same list.

    Common mistakes

    • Using the wrong index. Indexing starts at 0, so fruits[1] = "apple" replaces kiwi, not mango.
    • Assigning at the end. ages[4] = 1 on a four-item list throws IndexOutOfBoundsException. Assigning to an index replaces an element and never adds one. Use add to append.
    • Writing ages[1] + 5 alone. That computes 37 and throws the result away. Without the assignment, the list is unchanged.
    • Mixing types. A MutableList<Int> doesn't accept a string, so ages[0] = "old" doesn't compile.

    The set method and a loop

    Calling set directly has one difference from the bracket form: it returns the value that used to be stored at that index.

    val nums = mutableListOf(50, 40, 30)
    val old = nums.set(0, 15)
    println(old)
    println(nums)
    for (i in nums.indices) {
        nums[i] += 1
    }
    println(nums)
    
    50
    [15, 40, 30]
    [16, 41, 31]
    

    The loop shows how assignment by index updates every element in place. Updating the list inside the loop is safe here because the size never changes; adding or removing items while looping over the list is a different matter.

    Copies are separate

    Assigning a list to another variable gives two names for one list. To change a copy without touching the original, make the copy with toMutableList():

    val copy = nums.toMutableList()
    copy[0] = 0
    println(nums)
    println(copy)
    
    [16, 41, 31]
    [0, 41, 31]
    

    Key takeaways

    • list[i] = value replaces the element at index i and calls set for you.
    • It works on a MutableList, not on a read-only List.
    • The size doesn't change when you replace an element.
    Keep going with KotlinAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free