Scala ArrayBuffer class: methods, syntax, and examples

Summary: This page contains a large collection of examples of how to use the Scala ArrayBuffer class.

ArrayBuffer introduction

Use the ArrayBuffer class when you want to use a general-purpose, mutable indexed sequence in your Scala applications:

  • Mutable: you can change the elements in the collection, and resize the collection
  • Indexed: random access of elements is very fast; this means you can access elements quickly by their element number, such as people(12345432) (a linked list would be very slow for this purpose)

Just as the Vector class is the recommended “go to” class for immutable, indexed sequential collections, the ArrayBuffer class is recommended as the general-purpose collections class for mutable, indexed sequential collections.

ArrayBuffer is an indexed sequential collection. Use ListBuffer if you prefer a linear sequential collection that is mutable.

Notes about the following ArrayBuffer examples

The following examples are demonstrated in what I call a “CRUD+” order, meaning that the methods are shown in this order:

  • C — Create
  • R — Read
  • U — Update
  • D — Delete
  • + — demonstrates many methods available on the ArrayBuffer class

Import it

To use an ArrayBuffer you need to import it into the scope of your application:

import scala.collection.mutable.ArrayBuffer

In Scala, immutable collections are preferred, so when you want to use a mutable collection like ArrayBuffer, you need to import it first.

CREATE: How to create an initial, empty ArrayBuffer

Here are a few examples of how to create a new, empty ArrayBuffer:

val fruits = ArrayBuffer[String]()
val ints = ArrayBuffer[Int]()
val people = ArrayBuffer[Person]()

If you know your ArrayBuffer will need to hold a lot of elements you can create it with an initial size:

// ready to hold 100,000 ints
val buf = new ArrayBuffer[Int](100_000)

CREATE: How to create a new ArrayBuffer with initial elements

To create a new ArrayBuffer with initial elements, just specify the elements to add, like this:

val nums = ArrayBuffer(1, 2, 3)

val people = ArrayBuffer(
    Person("Al"),
    Person("Kim"),
    Person("Jim")
)

CREATE: Create a new ArrayBuffer by populating it

You can also create a new ArrayBuffer that’s populated with initial elements using a Range:

// to, until
(1 to 5).toBuffer                   // ArrayBuffer(1, 2, 3, 4, 5)
(1 until 5).toBuffer                // ArrayBuffer(1, 2, 3, 4)

(1 to 10 by 2).toBuffer             // ArrayBuffer(1, 3, 5, 7, 9)
(1 until 10 by 2).toBuffer          // ArrayBuffer(1, 3, 5, 7, 9)
(1 to 10).by(2).toBuffer            // ArrayBuffer(1, 3, 5, 7, 9)

('d' to 'h').toBuffer               // ArrayBuffer(d, e, f, g, h)
('d' until 'h').toBuffer            // ArrayBuffer(d, e, f, g)

('a' to 'f').by(2).toBuffer         // ArrayBuffer(a, c, e)

// range method
ArrayBuffer.range(1, 3)             // ArrayBuffer(1, 2)
ArrayBuffer.range(1, 6, 2)          // ArrayBuffer(1, 3, 5)

You can also use the fill and tabulate methods:

ArrayBuffer.fill(3)("foo")               // ArrayBuffer(foo, foo, foo)
ArrayBuffer.tabulate(3)(n => n * n)      // ArrayBuffer(0, 1, 4)
ArrayBuffer.tabulate(4)(n => n * n)      // ArrayBuffer(0, 1, 4, 9)

fill is a nice way to populate an ArrayBuffer with random data:

val r = scala.util.Random
ArrayBuffer.fill(5)(r.nextInt(10))         // ArrayBuffer(4, 4, 3, 9, 1)
ArrayBuffer.fill(5)(r.nextPrintableChar)   // ArrayBuffer(|, ], U, X, l)

If you have a populated ArrayBuffer you can also modify the values of each element in place with transform:

val a = ArrayBuffer.range(1,5)        // ArrayBuffer(1, 2, 3, 4)
a.transform(_ * 2)                    // a = ArrayBuffer(2, 4, 6, 8)

READ: How to access ArrayBuffer elements

As with other Scala sequence classes, you access ArrayBuffer elements by their index, inside parentheses:

val names = ArrayBuffer("bert", "ernie", "oscar")
names(0)    // "bert"
names(1)    // "ernie"
names(2)    // "oscar"

You can also read/access ArrayBuffer elements in for loops and for expressions, as shown here:

val oneToFive = ArrayBuffer(1, 2, 3, 4, 5)
for (i <- oneToFive) yield i         // ArrayBuffer(1, 2, 3, 4, 5)
for (i <- oneToFive) yield i * 2     // ArrayBuffer(2, 4, 6, 8, 10)
for (i <- oneToFive) yield i % 2     // ArrayBuffer(1, 0, 1, 0, 1)

UPDATE: Append, prepend, insert, and clear

To update existing elements in an ArrayBuffer:

val a = (1 to 4).toBuffer             // ArrayBuffer(1, 2, 3, 4)
a(2) = 50                             // ArrayBuffer(1, 2, 50, 4)
a.update(0, 10)                       // ArrayBuffer(10, 2, 50, 4)
a.update(3, 40)                       // ArrayBuffer(10, 2, 50, 40)

Updating also means adding new elements to an ArrayBuffer, and to do that, use the += and ++= methods:

Method Description
+= add a single element to an ArrayBuffer
++= add a sequence to an ArrayBuffer

You can also use these methods to append, insert, and prepend elements:

  • append, appendAll
  • insert, insertAll
  • prepend, prependAll

Examples

This is how to use += and ++=:

val nums = ArrayBuffer(1, 2, 3)   // ArrayBuffer(1, 2, 3)
nums += 4                         // ArrayBuffer(1, 2, 3, 4)
nums ++= List(5, 6)               // ArrayBuffer(1, 2, 3, 4, 5, 6)

Other ways to add elements to an ArrayBuffer:

val a = ArrayBuffer(1, 2, 3)      // ArrayBuffer(1, 2, 3)
a.append(4)                       // ArrayBuffer(1, 2, 3, 4)
a.appendAll(Seq(5, 6))            // ArrayBuffer(1, 2, 3, 4, 5, 6)

a.clear                           // ArrayBuffer()

val a = ArrayBuffer(9, 10)        // ArrayBuffer(9, 10)
a.insert(0, 8)                    // ArrayBuffer(8, 9, 10)
a.insertAll(0, Vector(6, 7))      // ArrayBuffer(6, 7, 8, 9, 10)
a.prepend(5)                      // ArrayBuffer(5, 6, 7, 8, 9, 10)
a.prependAll(Seq(1,2,3,4))        // ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

Note that when using insert, the first parameter is the position at which new elements should be inserted:

val a = ArrayBuffer('a', 'b', 'd')   // ArrayBuffer(a, b, d)
a.insert(2, 'c')                     // ArrayBuffer(a, b, c, d)

UPDATE: ArrayBuffer “in place” methods

Because ArrayBuffer is mutable, it has “in place” versions of the functional methods you find on immutable collections. As their names imply, they let you mutate an ArrayBuffer in place. These examples show how these “in place” methods work:

// an example ArrayBuffer:
val a = ArrayBuffer.tabulate(10)(i => i + 1)  // a: ArrayBuffer(1 .. 10)

a.dropInPlace(1)             // ArrayBuffer(2, 3, 4, 5, 6, 7, 8, 9, 10)
a.dropRightInPlace(1)        // ArrayBuffer(2, 3, 4, 5, 6, 7, 8, 9)
a.dropWhileInPlace(_ < 4)    // ArrayBuffer(4, 5, 6, 7, 8, 9)
a.filterInPlace(_ > 4)       // ArrayBuffer(5, 6, 7, 8, 9)
a.mapInPlace(_ * 10)         // ArrayBuffer(50, 60, 70, 80, 90)
a.takeInPlace(4)             // ArrayBuffer(50, 60, 70, 80)
a.takeRightInPlace(3)        // ArrayBuffer(60, 70, 80)
a.takeWhileInPlace(_ < 80)   // ArrayBuffer(60, 70)

// sortInPlace
val b = ArrayBuffer(20, 10, 15, 30, 25)
b.sortInPlace                // ArrayBuffer(10, 15, 20, 25, 30)
b.sortInPlaceWith(_ < _)     // ArrayBuffer(10, 15, 20, 25, 30)
b.sortInPlaceWith(_ > _)     // ArrayBuffer(30, 25, 20, 15, 10)

Note that the sorting examples require that the data type inside the ArrayBuffer is “sortable,” and I explain that more in How to sort Scala collections classes.

DELETE: Removing elements from an ArrayBuffer

An ArrayBuffer is a mutable sequence, so:

Method Description
-= Remove a single element or tuple of elements
--= remove multiple elements that are declared in another collection
clear removes all the elements from an ArrayBuffer
reduceToSize removes all elements after the index you specify
remove Use remove to delete one element by its position in the ArrayBuffer, or a series of elements beginning at a starting position
trimStart remove elements from the beginning
trimEnd remove elements from the end

Examples

-= and --=:

val a = ArrayBuffer.range('a', 'h')   // ArrayBuffer(a, b, c, d, e, f, g)
a -= 'a'                              // ArrayBuffer(b, c, d, e, f, g)
a --= Seq('b', 'c')                   // ArrayBuffer(d, e, f, g)
a --= Set('d')                        // ArrayBuffer(e, f, g)

remove:

val a = ArrayBuffer.range('a', 'h')   // ArrayBuffer(a, b, c, d, e, f, g)
a.remove(0)                           // ArrayBuffer(b, c, d, e, f, g)
a.remove(2, 3)                        // ArrayBuffer(b, c, g)

trimStart and trimEnd:

val a = ArrayBuffer.range('a', 'h')   // ArrayBuffer(a, b, c, d, e, f, g)
a.trimStart(2)                        // ArrayBuffer(c, d, e, f, g)
a.trimEnd(2)                          // ArrayBuffer(c, d, e)

clear:

val a = ArrayBuffer.range('a', 'h')   // ArrayBuffer(a, b, c, d, e, f, g)
a.clear                               // ArrayBuffer[Char] = ArrayBuffer()

reduceToSize:

val a = ArrayBuffer.range('a', 'h')   // ArrayBuffer(a, b, c, d, e, f, g)
a.reduceToSize(4)                     // ArrayBuffer(a, b, c, d)

MORE: Using functional methods with ArrayBuffer

Even though ArrayBuffer is a mutable sequence, you can also use all of the usual functional methods to create new values from an ArrayBuffer:

val a = ArrayBuffer.range(0,5)        // ArrayBuffer(0, 1, 2, 3, 4)
val b = a.head                        // b = 0
val b = a.tail                        // b = ArrayBuffer(1, 2, 3, 4)
val b = a.drop(2)                     // b = ArrayBuffer(2, 3, 4)
val b = a.dropWhile(_ < 3)            // b = ArrayBuffer(3, 4)
val b = a.take(2)                     // b = ArrayBuffer(0, 1)
val b = a.takeWhile(_ < 3)            // b = ArrayBuffer(0, 1, 2)
val b = a.map(_ * 2)                  // b = ArrayBuffer(0, 2, 4, 6, 8)
val b = a.filter(_ > 2)               // b = ArrayBuffer(3, 4)

val a = ArrayBuffer.range('a', 'e')   // ArrayBuffer(a, b, c, d)
val b = a.splitAt(2)                  // b = (ArrayBuffer(a, b),ArrayBuffer(c, d))

You can also convert ArrayBuffer into other Scala sequences:

val a = ArrayBuffer.range(0,4)        // ArrayBuffer(0, 1, 2, 3)
val b = a.toList                      // b = List(0, 1, 2, 3)
val b = a.toVector                    // b = Vector(0, 1, 2, 3)
val b = a.toSet                       // b = Set(0, 1, 2, 3)

For many more examples of using functional methods on Scala sequences, see my Examples of Scala Vector methods tutorial.

Scala ArrayBuffer summary

I hope these ArrayBuffer examples are helpful. If I made a mistake, or you know another way to do something with an ArrayBuffer I haven’t shown, leave a note in the Comments section.