How to add elements to a List in Scala

This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 11.3, “How to Add Elements to a List in Scala”

Problem

You want to add elements to a List that you’re working with.

Solution

“How do I add elements to a List?” is a bit of a trick question, because a List is immutable, so you can’t actually add elements to it. If you want a List that is constantly changing, use a ListBuffer (as described in Recipe 11.2), and then convert it to a List when necessary.

To work with a List, the general approach is to prepend items to the list with the :: method while assigning the results to a new List:

scala> val x = List(2)
x: List[Int] = List(2)

scala> val y = 1 :: x
y: List[Int] = List(1, 2)

scala> val z = 0 :: y
z: List[Int] = List(0, 1, 2)

Rather than continually reassigning the result of this operation to a new variable, you can declare your variable as a var, and reassign the result to it:

scala> var x = List(2)
x: List[Int] = List(2)

scala> x = 1 :: x
x: List[Int] = List(1, 2)

scala> x = 0 :: x
x: List[Int] = List(0, 1, 2)

As these examples illustrate, the :: method is right-associative; lists are constructed from right to left, which you can see in this example:

scala> val list1 = 3 :: Nil
list1: List[Int] = List(3)

scala> val list2 = 2 :: list1
list2: List[Int] = List(2, 3)

scala> val list3 = 1 :: list2
list3: List[Int] = List(1, 2, 3)

Any Scala method that ends with a : character is evaluated from right to left. This means that the method is invoked on the right operand. You can see how this works by analyzing the following code, where both methods print the number 42:

object RightAssociativeExample extends App {
    val f1 = new Printer
    f1 >> 42
    42 >>: f1
}

class Printer {
    def >>(i: Int) { println(s"$i") }
    def >>:(i: Int) { println(s"$i") }
}

The two methods can also be invoked like this:

f1.>>(42)
f1.>>:(42)

but by defining the second method to end in a colon, it can be used as a right-associative operator.

Though using :: is very common, there are additional methods that let you prepend or append single elements to a List:

scala> val x = List(1)
x: List[Int] = List(1)

scala> val y = 0 +: x
y: List[Int] = List(0, 1)

scala> val y = x :+ 2
y: List[Int] = List(1, 2)

You can also merge lists to create a new list. See Recipe 11.5 for examples.

Discussion

If you’re not comfortable using a List, but want to use a mutable, linear list, see Recipe 11.2, “Creating a Mutable List” for examples of how to use the ListBuffer class.

The ListBuffer is a mutable, linear sequence (as opposed to an indexed sequence, like an Array or ArrayBuffer), and is similar to working with a StringBuffer or StringBuilder in Java. Just as you’d convert those classes to a String when needed, you convert a ListBuffer to a List when needed. Programmers from other backgrounds may be more comfortable with the :: approach. A nice benefit of Scala is that it offers both options.

See Also

  • Recipe 11.2, “Creating a Mutable List”
  • Recipe 10.4, “Understanding the Performance of Collections”