Scala arrays

One of the very first data structures used in every language is the array. Scala provides two types of arrays, implemented using the JVM facilities: the Array class and the ArrayBuff class. The first one is used when the length of the array is known in advance, while the second one provides a dynamically growing type of array.

Here I’m going to declare a new Array:

scala> val ary = Array[Int](1, 2, 3)
ary: Array[Int] = Array(1, 2, 3)

The array declared here has type Int and contains the numbers 1, 2 and 3. Scala is well known for its type inference which is the ability to infer (deduct, figure out) the type of something just by using the returning type of the expression it is generating it. In this case, the Array contains integers, so its type is Array[Int]. Scala is able to guess this information on its own, so I don’t really need to specify it:

scala> val ary = Array(1, 2, 3)
ary: Array[Int] = Array(1, 2, 3)

The type of ary is once again Array[Int] even if I have not declared it.

You could have noted that I’ve not used the new keyword to declare the new array. Is this a particularity of Scala? Does Scala lacks the new keyword? Not at all. The new keyword is the right way to declare a new object. So, were that keyword has gone? To answer this question I need to mention another peculiar aspect of Scala: the companion objects.

Scala classes lack static methods. To balance this, Scala provides a more powerful concept. You guessed: I’m talking about companion objects. The Array class has its Array companion object. You can see it clearly in the Scala documentation. Beside the Array class the docs display to icons: a rounded O and a rounded C. The C means a class named Array exists. The O means an object named Array exists. The two icons lead to different pages in the docs. In the object Array page we can find a rich list of apply() methods which happen to be the method called by Scala behind the scenes when you append some arguments inside parenthesis to the name of an object.

Scala array

To resume, the expression:

scala> val ary = Array(1, 2, 3)

and the expression:

scala> val ary = Array.apply(1, 2, 3)

are completely equivalent.

Now, let’s take a look at the ArrayBuff variable brother. First of all let’s see what happens if I try to add another element to the ary object:

scala> ary += 5;
<console>:9: error: reassignment to val
              ary += 5;

The REPL shows no mercy: I can’t add an element to the array. Now I replace the Array with an ArrayBuff which I must import first:

scala> import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.ArrayBuffer

scala> val ary = ArrayBuffer(1, 2, 3);
ary: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3)

scala> ary += 5;
res1: ary.type = ArrayBuffer(1, 2, 3, 5)

Nice! The ArrayBuff class has been imported, then used to redeclare ary and now I’m able to append the new element. When I’m done manipulating it, I can convert the ArrayBuff into a plain Array just by doing:

scala> val aryflat = ary.toArray
aryflat: Array[Int] = Array(1, 2, 3, 5)

This is a just scraping the surface of arrays in Scala. Another peculiar idiomatic form in Scala is assigning a new value to a position:

scala> val ary = Array(1, 2, 3)
ary: Array[Int] = Array(1, 2, 3)

scala> ary(2) = 7

Here I’ve declared a new Array and then changed its element at position 2 (it’s the third element, as you’ve supposed) to 7. Now I expect the element of the array to be (1, 2, 7). Let’s check it:

scala> println(ary)
[I@53dc5341

Ouch! Not exactly what I was expecting. A better way is to used the mkString() method of the Array class:

scala> println(ary.mkString(","))
1,2,7

Yes, the third element now is no longer 3, but 7. Now: what exactly happened when the ary array was used on the left side of the equal sign? Well, do you remember the apply() method mentioned before? There’s a related method called update() which is called for you when you use an object on the left of an equal sign. So the previous assignment is equivalent to:

scala> ary.update(2, 7)