Updated April 4, 2023
Introduction to Scala Collections
Collections in Scala are nothing but a container where the list of data items can be placed and processed together within the memory. It consists of both mutable (scala.collection.mutable) and immutable (scala.collection.immutable) collections which in-turn varies functionally with Val and Var and also, Scala collections provide a wide range of flexible built-in methods, which can be used to perform various operations like transformations & actions, directly on the data items.
Scala Collections Framework
At a very high-level collection contains Seq, Set & Map. All of them are the child of Traversable traits. Do keep it in mind, All of the Childs of Traversable (Parent) are Traits and not classes which makes it easier to implement in the code snippet, without having the need to create the object before calling it.
Let us discuss it in detail as follows:
- Reference – Book: A Beginner’s Guide to Scala, Object Orientation and Functional Programming
- Traversable: helps us to traverse through the entire collection and it implements the behavior that are common to all the collections irrespective of the data types. It simply means Traversable lets us traverse the collections repeatedly in terms of for each method.
- Iterable: gives us an iterator, which lets you loop through a collection’s elements one at a time.
Mutable & Immutable Collections
Scala Provides 2 varieties of collections. They are:
- Mutable
- Immutable
Mutable Collections
This type of Collection can be updated, which means, every time you try to add an element to the collection, it just appends to the same object. you can add, update and remove the elements from the existing mutable collection.
Example:
- AnyRefMap
- ArrayBuffer
- ArrayBuilder
- ArraySeq
- ArrayStack
- BitSet
- DoubleLinkedList
- HashMap
- HashSet
- LinkedHashMap
- LinkedHashSet
- LinkedList
- Stack
- StringBuilder
- TreeSet
- WeekHashMap, etc.
Immutable Collections
This type of collection can never be changed. We can still see the methods that look like adding/ updating/ removing elements from the collection. But it actually creates a new collection internally and leaves the old one unchanged.
Example:
- BitSet
- HashMap
- HashSet
- List
- ListMap
- ListSet
- LongMap
- NumericRange
- Stack
- Stream
- StreamIterator
- TreeMap
- TreeSet
- Vector
- IndexedSeq, etc..
String & Lazy Collection
Whenever we perform any data transformations using a filter, map, min, max, reduce, fold, etc.., on collections, it basically transforms it into another collection. There could be some collections that allow Strict Transformations means, the memory of the elements are allocated immediately when the elements are evaluated and results in the new collection. In a Lazy Collection, the transformations will not create another collection upfront. It means, the memory will not be allocated immediately and it creates the new collection when there is a demand. Collection classes can be converted into Lazy Collection by creating a view on the collection.
Let us look into the Scala REPL example for a better understanding.
Example:
Code:
object Demo {
def main(args: Array[String]) {
val ls = (0 to 5).toList
println("List is: " + ls);
}
}
Output:
While creating the collection – List, the memory is allocated immediately and when we try to call the list, we are able to find the list of elements as below.
ls
res0: List[Int] = List(0, 1, 2, 3, 4, 5) //collection items of ls is allocated to res0. Hence, it created the memory immediately.
To Create a Lazy Collection:
object Demo {
def main(args: Array[String]) {
val ls = (0 to 5).toList
val lsLazy = ls.view
println("View: " + lsLazy);
}
}
lsLazy: scala.collection.SeqView[Int] = View(?)
Code:
object Demo {
def main(args: Array[String]) {
val ls = (0 to 5).toList
val lsLazy = ls.view
println("max "+lsLazy.max);
}
}
object Demo {
def main(args: Array[String]) {
val ls = (0 to 5).toList
val lsLazy = ls.view
lsLazy.foreach(println)
}
}
Let us investigate some of the basic methods that come with the Collections:
Mutable Collections: ArrayBuffer
Example:
Code:
object Demo {
def main(args: Array[String]) {
val arrBuff = (0 to 5).toBuffer
println(" "+arrBuff);
}
}
Output:
Now, let’s try adding an element to the existing ArrayBuffer Collection.
object Demo {
def main(args: Array[String]) {
val arrBuff = (0 to 5).toBuffer
arrBuff += 5
println(" "+arrBuff);
}
}
Look at the below result, if you look closer, you could find that data item “5” has been appended to the existing collection.
Note: += is a method that is used to append the element to the original collection. i.e., adds the new element to the collection and reassigns the result to the original collection.
- :+ –> this method used to append the element in the copy of an object.
- +: –> this method used to prepend the element in the copy of the object.
Example:
Code:
object Demo {
def main(args: Array[String]) {
val arrBuff1 = (0 to 5).toBuffer
println(" "+arrBuff1);
}
}
Output:
Code:
object Demo {
def main(args: Array[String]) {
val arrBuff1 = (0 to 5).toBuffer
arrBuff1 +=66
println(" "+arrBuff1);
}
}
Output:
- res24: scala.collection.mutable.Buffer[Int] = ArrayBuffer(0, 1, 2, 3, 4, 5, 66) // added in the copy, not the original
- res25: scala.collection.mutable.Buffer[Int] = ArrayBuffer(0, 1, 2, 3, 4, 5) // check the original collection and note that the collection items remain unchanged.
Immutable Collection: List
Example:
Code:
object Demo {
def main(args: Array[String]) {
val ls = (1 to 5).toList
println(" "+ls);
}
}
object Demo {
def main(args: Array[String]) {
val ls = (1 to 5).toList
ls :+5
println(" "+ls);
}
}
map –> This method helps us to traverse through the collection and allows us to transform the incoming data item to the desired output.
Example:
Code:
object Demo {
def main(args: Array[String]) {
val ls = (1 to 5).toList
println("" + ls.map(e=> (e*2)));
}
}
Output:
foreach –> This method functions the same way as map, except that it cannot return the values.
Example:
Code:
object Demo {
def main(args: Array[String]) {
val ls = (1 to 5).toList
ls.foreach(println)
}
Output:
Conclusion
As we have seen so far, collections are way useful to store and retrieve formatted items of the respective data types. Also, it comes with various methods to add/ change or delete items from the collection. It is even adaptable to use in most critical scenarios, as it provides mutable and immutable collections.
Recommended Articles
We hope that this EDUCBA information on “Scala Collections” was beneficial to you. You can view EDUCBA’s recommended articles for more information.