Start learning free

LESSON 94 OF 414 · ARRAYS I

Arrays in Scala: List, Array and ArrayBuffer

Lesson Read the full explanation

In Scala, a List stores multiple values in one variable. Lists keep their elements in order and use zero-based indexing, so the first element is at index 0.

Creating a List:

val sandwich = List("peanut butter", "jelly", "bread")

Accessing elements:

val numbers = List(50, 60, 70)
val data = numbers(1)

// data is 60

Indexing with ():

Scala indexes collections with parentheses, not square brackets — write numbers(0), not numbers[0]. The same applies to a fixed-size Array, which you create with Array(...):

val arr = Array(1, 2, 3)
val first = arr(0)   // 1  — use (), not arr[0]

That's the numbers(1) style you see throughout the coding tutorials.

Getting the size:

println(numbers.size)

Iterating:

for (ingredient <- sandwich) {
    println(ingredient)
}

When you need a list that can be changed, Scala also has scala.collection.mutable.ArrayBuffer.


Assignment
Follow the Coding Tutorial and let's create some lists.


Hint
Use List(...) to create a Scala list, or ArrayBuffer(...) for one you can change.


STEP 1 OF 2
    Ctrl + Enter to check

    SCALA · ARRAYS I

    Arrays in Scala, explained

    Three ways to hold a sequence

    Scala has several types for an ordered group of values. Three are common in beginner code, and they differ in whether the contents or the size can change:

    TypeSizeElements
    Listfixedcannot be changed
    Arrayfixedcan be changed
    ArrayBuffercan grow and shrinkcan be changed

    All three keep their items in order and count positions from zero, so the first element is at index 0.

    List

    A List is immutable. Once built, it never changes:

    val sandwich = List("peanut butter", "jelly", "bread")
    val numbers = List(50, 60, 70)
    val data = numbers(1) // 60
    println(numbers.size) // 3
    for (ingredient <- sandwich) {
        println(ingredient)
    }
    

    The loop prints peanut butter, jelly and bread, one per line. Scala reads an element with parentheses, numbers(1). Square brackets are used for type parameters such as List[Int], so numbers[1] doesn't compile.

    You can't assign to a list position: numbers(0) = 5 is a compile error, because List has no update method. To get a changed copy, call updated. sandwich.updated(1, "honey") returns a new list List(peanut butter, honey, bread) and leaves sandwich as it was.

    Array

    An Array has a fixed length, but you can assign to its positions. It is created with Array(...):

    val arr = Array(1, 2, 3)
    val first = arr(0) // 1
    arr(0) = 10        // allowed
    

    It is indexed the same way as a list, with parentheses.

    ArrayBuffer: the resizable one

    When you need a collection that can grow and shrink, use scala.collection.mutable.ArrayBuffer. It is the closest Scala type to a resizable array in other languages. You create it with its companion object, so there is no new, and the element type is inferred:

    val fruits = scala.collection.mutable.ArrayBuffer("mango", "kiwi", "grapefruit")
    fruits += "plum"      // now 4 elements
    fruits.remove(0)      // removes "mango"
    println(fruits)       // ArrayBuffer(kiwi, grapefruit, plum)
    

    += appends an element, and remove(i) deletes the element at index i. You can import the class once with import scala.collection.mutable.ArrayBuffer and then write just ArrayBuffer(...).

    Choosing between them

    Use a List when the values should never change after they are built. This is the default in most Scala code, and it is safe to pass around. Use an Array when you know the size and want to overwrite elements in place. Use an ArrayBuffer when you will add or remove items while the program runs, as when collecting results one by one.

    The three share the same reading syntax and many methods, including size, length, head and last, so switching from one to another usually changes only the line that creates the collection.

    The exercise

    The lesson wants two ArrayBuffer variables:

    1. fruits holding "mango", "kiwi" and "grapefruit".
    2. ages holding 14, 32, 50 and 21.
    val fruits = scala.collection.mutable.ArrayBuffer("mango", "kiwi", "grapefruit")
    val ages = scala.collection.mutable.ArrayBuffer(14, 32, 50, 21)
    

    Both are declared with val. That only means the variable can't be pointed at another buffer. Appending to ages later is still allowed.

    Gotchas

    • Parentheses, not brackets. ages(0) reads an element. ages[0] is an error.
    • mutable in the name. Plain List, Vector and Map are available without an import and are immutable. The mutable versions live in scala.collection.mutable.
    • Printing. Lists and buffers print readably (List(1, 2, 3), ArrayBuffer(1, 2, 3)), but a plain Array does not. Use mkString for arrays.

    Getting the size

    Each of the three reports how many elements it holds with size. length returns the same number. For a list of three items, numbers.size is 3. The last valid index is always one less than the size, a fact you will use constantly in the next lessons.

    Key takeaways

    • List is immutable, Array has a fixed size, and ArrayBuffer can change size.
    • Index with parentheses, starting at 0.
    • Use ArrayBuffer(...) from scala.collection.mutable when the collection has to grow.
    Keep going with ScalaAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free