Scala Collections: Part 1 - Overview of the hierarchy
One of the first things that impressed me with Scala was the Scala Collections. It's flexible and has a wide range of operations that makes it easy to work with different types of data.
So to get more familiar with Scala Collections API, I've started this mini series. Here I'll explore what the Scala Collections are capable of, by solving different problems.
In this first part, I'll give a quick overview of how the collection hierarchy is put together.
The Scala Collection hierarchy
Traversable is the top of the Collection hierarchy.
It defines a lot of the great operations that the Scala Collections has to offer. The only abstract method Traversable contains, is a
def foreach[U](f: Elem => U): Unit
This method is essential to the operations in Traversable. The
foreach method should traverse all the elements of the collection, while executing the function
f on each of the elements. The actual implementation on the other hand, can differ a lot to make sure it's optimized for the different collections.
Contains an abstract
iterator method that all sub-collections must define. Iterable also implements the abstract
foreach method from Traversable using the iterator. But as I mentioned earlier, a lot of the sub-collections override this implementation to optimize.
Sequences differ a bit from normal Iterables. Sequences has a defined order and length. Seq has two sub-traits.
LinearSeq is defined in terms of three abstract methods.
isEmpty- tells if the list is empty
head- first element in the sequence
tail- all elements in the sequence except the first one
It's assumed that sub-collections of LinearSeq will have good performance on their implementations of these methods. Typical collections that extends LinearSeq are Lists and Streams.
IndexedSeq is defined in terms of two abstract methods.
apply- Find element by its index
length- The length of the sequence
It's assumed that sub-collections of IndexedSeq will have good performance on random access patterns. Typical indexed sequences are ArrayBuffer and Vectors. Vectors are a bit special, because their performance is good both on indexed and linear access.
Strings and Arrays also fit into this group, but it's worth mentioning that they are not subclasses of Seq. They are actually taken from Java. But by the help of different conversions, Scala offers the same operations on Strings and Arrays as on other sequence collections.
Sets are Iterables without duplicate elements.
Maps are Iterables that contains pairs of keys and values.
Mutable and Immutable
Scala distinguishes between mutable and immutable collections. For those collections that comes in both variants, Scala chooses immutable by default. So if you want a mutable variant, you have to explicitly write it.
With a better understanding of the collection hierarchy, we'll continue exploring the different operations we can use on the collections.
If you don't want to miss the next parts, make sure to subscribe at the end of this post.