What a static array is
An array stores several values of the same type in one variable, in order. A static (or fixed) array has its length decided when it is created, and that length never changes. In Scala this is the Array[T] class, where T is the element type: Array[Int] holds integers and Array[String] holds strings.
Use an array when you know how many items you need up front and want fast access by position. When the number of items has to grow or shrink, a collection such as ArrayBuffer fits better.
Two ways to create one
With a length: new Array[T](n)
This allocates an array of n slots and fills them with the default value for the type:
val arrayOfStrings = new Array[String](3)
val numbers = new Array[Int](20)
The element type goes in square brackets and the length in parentheses. The slots are not empty: a String array starts with three null values, an Int array with zeros and a Boolean array with false. Printing arrayOfStrings.mkString(",") gives null,null,null, and numbers.sum is 0.
With values: Array(...)
To fill the array at creation, list the values inside Array(...), separated by commas:
val arrayOfStrings = Array("AlgoCademy", "coding", "static arrays")
There is no new here, because Array(...) calls the companion object's apply method. Scala infers the element type from the values, so this is an Array[String] of length 3. All values must fit one type. Array(1, 2.5) becomes an Array[Double], because the integer is widened to a double.
Using a fixed array
After creation, you can read and replace elements by index, and ask for the length. The length is fixed, but the contents are not:
val nums = new Array[Int](3)
nums(1) = 7
println(nums.mkString("[", ", ", "]")) // [0, 7, 0]
println(nums.length) // 3
Only slot 1 changed. The other two keep the default 0. Writing to an index that doesn't exist, such as nums(3) = 1, throws an ArrayIndexOutOfBoundsException, because the array has no fourth slot to hold it.
The exercise
The lesson asks for two arrays:
- An integer array named
numberswith 20 elements. Use the length form, since no values are given: the element type isIntand the length is20. - A string array named
fruitsholding"mango","kiwi"and"grapefruit". Use the value form, since the contents are known.
val numbers = new Array[Int](20)
val fruits = Array("mango", "kiwi", "grapefruit")
Gotchas
valfixes the variable, not the contents. Avalarray always refers to the same array, but its elements can still be changed. You can't givenumbersa different array later.Array(3)is notnew Array[Int](3).Array(3)is an array with one element, the number 3.new Array[Int](3)is an array of three zeros.- Don't print an array directly.
println(fruits)shows a type-and-address string, not the contents. Usefruits.mkString(", ")orfruits.toList. - The length can't change. There is no way to add a 21st element to
numbers. You would create a new array or use anArrayBuffer.
Why a default value matters
The defaults make a freshly created array safe to read. A new Array[Int] works as a set of counters that all start at zero. A new Array[String] is different: reading a slot before you assign it gives null, and calling a method on it, such as .length, fails with a NullPointerException. Assign every slot before you use it, or build the array from values with Array(...).
Key takeaways
new Array[T](n)makesndefault-valued slots: zeros,falseornull.Array(a, b, c)makes an array from values and infers the type.- An array's length is fixed when it is created.
