Start learning free

LESSON 103 OF 414 · ARRAYS I

Array Push in Scala: Appending to an ArrayBuffer

Lesson Read the full explanation

A Scala List is immutable. When you need to append elements in place, use scala.collection.mutable.ArrayBuffer.

val arr = scala.collection.mutable.ArrayBuffer(1, 2, 3)
arr += 4

// arr is now ArrayBuffer(1, 2, 3, 4)

Assignment
Follow the Coding Tutorial and append an item.


Hint
Use += with an ArrayBuffer.


STEP 1 OF 2
    Ctrl + Enter to check

    SCALA · ARRAYS I

    Array Push in Scala, explained

    Why a List can't do this

    Many languages have an array that you can grow with push or append. In Scala, the two everyday sequence types differ in an important way:

    • A List is immutable. It never changes after it is created. Operations like :+ build and return a new list and leave the original alone.
    • An Array is mutable but has a fixed size, so it can't grow.
    • An ArrayBuffer, from scala.collection.mutable, is mutable and growable, so it plays the role of a push-able array.

    The lesson uses the full name scala.collection.mutable.ArrayBuffer because the type is not imported by default.

    Appending with +=

    The += operator adds one element at the end of a buffer, changing the buffer itself:

    val arr = scala.collection.mutable.ArrayBuffer(1, 2, 3)
    arr += 4
    
    println(arr)   // ArrayBuffer(1, 2, 3, 4)
    

    Notice that arr is declared with val. That is fine, because val only prevents reassigning the name arr. The buffer it refers to can still change. Appending is always at the end, so the new element gets the index size - 1.

    Other ways to add elements to a buffer:

    val arr = scala.collection.mutable.ArrayBuffer(1, 2, 3)
    
    arr.append(4)        // same as arr += 4
    arr ++= List(5, 6)   // append several elements at once
    arr.prepend(0)       // add at the front
    arr.insert(1, 99)    // add at index 1, shifting later elements right
    
    println(arr)         // ArrayBuffer(0, 99, 1, 2, 3, 4, 5, 6)
    

    How += reads

    On a mutable buffer, arr += 4 is a method call that changes arr and gives back the same buffer. It is not shorthand for arr = arr + 4, which is why it works with a val. The buffer is stored as one growable block of memory, so adding at the end is cheap on average, while adding at the front or the middle with prepend or insert has to shift the elements after it.

    Elements are added one at a time and keep their order, so after arr += 4 followed by arr += 5 the buffer ends with 4, 5.

    The exercise

    The lesson starts with two buffers:

    val fruits = scala.collection.mutable.ArrayBuffer("mango", "kiwi", "grapefruit")
    val ages = scala.collection.mutable.ArrayBuffer(14, 32, 50, 21)
    
    1. Append "apple" to fruits. After fruits += "apple" it holds four fruits and "apple" is last.
    2. Append 10 and then 23 to ages. += takes one value, so it is used twice, in that order. The order matters because each append goes to the end: 10 goes first and 23 after it, so 23 is last.

    The complete solution:

    val fruits = scala.collection.mutable.ArrayBuffer("mango", "kiwi", "grapefruit")
    val ages = scala.collection.mutable.ArrayBuffer(14, 32, 50, 21)
    
    fruits += "apple"
    ages += 10
    ages += 23
    

    Afterwards fruits is ArrayBuffer(mango, kiwi, grapefruit, apple) and ages is ArrayBuffer(14, 32, 50, 21, 10, 23).

    Mistakes to avoid

    • Using += on an immutable List. A List has no += that works on a val, and the compiler reports that += is not a member of List[Int]. To "add" to a list, build a new one with :+: val bigger = list :+ 4. The original list is unchanged. With a var, list = list :+ 4 works, but each append copies the list, which is slow for long lists.
    • Expecting :+ to change a buffer. On a buffer it also returns a new collection and leaves the buffer as it was. Use += to change the buffer itself.
    • Appending the wrong type. The buffer's element type is fixed by its first elements. A buffer of Int rejects ages += "ten" when the program is compiled.

    Key takeaways

    • Use scala.collection.mutable.ArrayBuffer when you need to grow a sequence in place.
    • buffer += value appends one element at the end.
    • val fixes the name, not the contents of a mutable collection.
    • A List is immutable: "adding" gives a new list.
    Keep going with ScalaAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free