Scala: Arrays, Lists, Sets and Maps

Despite all Scala code is translated to Java code, there are some differences between Scala Collections and Java Collections. In this post we will try to explain four types of collections: Arrays, Lists, Sets and Maps.

Arrays

In Scala, in contrast to Java, there is an Array object and it can be created in the same way as Java does. However, the syntax differs. The first one is the classical way to create an object.

var classicWay = new Array[String](3)
classicWay(0) = “The”
classicWay(1) = “classic”
classicWay(2) = “way”

There are two important differences to notice. The way to specify the type of the Array is [] instead of <>. The other one is the way to instance the array, in Scala we use the () instead of []. There is also another way to create and initialize an Array, which is less verbose and more compact.

var compactWay = Array(“I”,”like”,”this”,”way”)

As it can be seen, there is no need to specify the type of the Array, the compiler will infer that the type is String. Here there is another difference, we use the companion class to get an instance of Array. Companion classes will be explained in another post, but they can be seen as static classes or utility classes.
Obviously, we can’t access a position of the Array with the [] operator, instead, the () operator is used. For instance:

print(compactWay(1))
compactWay(0) = “We”

It will be transformed into:

print(compactWay.apply(1))
compactWay.update(0,”We”)

Lists

Lists in Scala are always immutable (in Java they can be mutable), they are designed to enable a functional style programming. That means that, once created, a Scala List can’t be modified. But there are operators on Lists, so maybe you would be wondering why there are operators on Lists if they are immutable objects. As in Strings, when you invoke any operation on a List, another List is created and returned when an operator is applied. Maybe, the two main operators are ::: and :: . The first one is the operator for list concatenation. The second one is the operator to prepend an element to a List. Yes, you read it well: prepend (in Scala you can’t append elements to a list). This is because prepend an element at the beginning of a list is a constant-time operation, whereas append is a linear-time operation. Usually, the owner of an operation is the left operand, but in :: the owner is the right operand. Here there are some examples.

val list1 = List(“This”,”is”)
val list2 = List(“a”,”list”)
val list3 = list1 ::: list2
val list4 = “Hey!” :: list3
println(list1)
println(list2)
println(list3)
println(list4)

List1 and list2 remain immutable, they didn’t change. List3 is a new list resulting of concatenating list1 and list2. In list4, the String “Hey!” is prepended to list3. The complete api of List object can be found here.

Sets

There are two kinds of Sets, the immutable and the mutable one. The difference between mutable and immutable objects is that when an object is immutable, the object itself can’t be changed. The most known immutable object in Java is String: once you have created a String, it remains the same until it is destroyed.

By default, Scala uses the immutable Set. If you want to use the mutable Set, you’ll have to import the class. The hierarchy of the Set is the following:

Hierarchy for the Scala Set object

It’s not a problem to change between mutable and immutable collections, since all of them share the same contract. In most cases, no change will be necessary.

You can create a Set in the same way you create a List. The most useful operations are + and +=, but the second one it’s only available in mutable Sets. In the immutable Sets  mySet += “foo”  is transformed to mySet = mySet.+(“foo”). Here there is a simple example of immutable sets:

var trilogies = Set(“The Godfather”, “Lord of the Rings”)
trilogies += “Millennium”
println(trilogies)

In this example, a new Set is created in line 2. If we import the mutable Set, in this same line, the trilogies set will be modified:

import scala.collection.mutable.Set
var trilogies = Set(“The Godfather”, “Lord of the Rings”)
trilogies += “Millennium”
println(trilogies)

Maps

As in Sets, there are two kinds of Maps, the immutable and the mutable ones. The hierarchy of Map is analog to Map’s hierarchy:
Hierarchy of Scala Set
There are two ways to create a Map in Scala, one of them can only be used with the mutable Maps:

import scala.collection.mutable.Map
var steps = Map[Int, String]()
steps += (1 -> “Go straight on”)
steps += (2 -> “Take the second turn on the left”)
steps += (3 -> “It’s opposite the hairdresser”)
println(steps(3))

Obviously, this Map needs to be mutable, because it has been modified since its creation. Ok, we know how to create mutable Maps, but how immutable Maps can be created?

var steps = Map (1 -> “Go straight on”, 2 -> “Take the second turn on the left”, 3 -> “It’s opposite the hairdresser”)
print(steps(3))

Here again, there is no need to specify the type of the Array, the compiler will infer that the type is Int for the keys and String for the values. The operator -> is useful for creating Tuples. A Tuple can be seen as an array of objects, but they don’t need to share the same type.

12 Responses

  1. Remind me why do we still write applications using java… btw, cool article, again.

  2. I suppose we are still writing applications in Java only for keeping us in our comfort zone.
    Maybe we should step out of our comfort zone and give new languages a try.

  3. We are writing apps in Java because my tired eyes can’t distinguish if that is a 3 or a 2 “:”

    val list3 = list1 ::: list2
    val list4 = “Hey!” :: list3

  4. Maybe in a plain text editor could be quite confusing, but it gets better with an IDE like Eclipse.
    By the way, thanks for leaving a comment.

  5. Only a fool will axe his own langauge by patronizing functional
    programmers instead of object oriented gurus.

  6. Hi Josef, can I “clone” your article (with linking to your post) with python examples? I am surprised that the easy handling with list/set/map is new for all the java coders.

    • Hi Christian,
      of course you can “clone” mi article, just link it to my blog. Could you please then post a comment here with a link to your post?
      Thanks!

  7. Hi Josef! Do you know how to work with a motor engine rules and dinamic entities with Scala? I need that for a crazy project that I’m actually involved and I don’t wanna lose my hair ;)

  8. Dude! you will lose your hair, it’s a fact!
    I will investigate this, but I can promise nothing.

  9. Hey! I’ve found two links about that! I wouldn’t expect so much interest for Scala!
    Neo4J for Scala
    http://wiki.neo4j.org/content/Scala
    and Drools for Scala
    http://github.com/memelet/drools-scala

    Wow!

  10. They seem very similar. What are the differences between them? When would i use a list? Why not an array? When would I use map?

    • Hi Roderick,
      Usually you would use a List or an Array when the order of the elements in the collection is relevant. The main difference between Lists and Arrays is that the latter are more efficient for random access, so you can access any element on the collection at any time. On the other hand, Lists suit perfectly to the recursion pattern: process head, recursive call with the tail.
      Some example of this would be:

      def listRecursion(accum: Int, list: List[Int]): Int = list match {
      case Nil => accum
      case head::tail => listRecursion(accum + head, tail)
      }

      Maps are completely different from Lists and Arrays because they hold relationships between keys and values. So the use case is more similar to a Dictionary than a normal Collection you might want to traverse.

Leave a reply to Josep Prat Cancel reply