Greetings, coding enthusiasts! Today, we're diving into Scala's diverse toolbox to unravel a fundamental data structure: Lists! Much like a shopping list or a task list, Scala allows us to create a list of items. With our eyes fixed on mastering Lists, we're geared up for a journey into the world of Scala!
Have you ever created a to-do list? It stores your tasks in one place, right? Likewise, Scala's Lists can store multiple items of homogeneous types. There are two primary types of lists in Scala: immutable and mutable.
Immutable lists, once created, cannot be changed. This means you can't update existing elements, add new elements, or remove elements from an immutable list. On the other hand, mutable lists can be modified — you can add, change, and remove elements. Consider this example of a to-do list:
Scala1@main def run: Unit = 2 val myToDoList = List("buy groceries", "take out the trash", "send emails") 3 println(myToDoList) // This will print the list in a nicely formatted way
By default, Lists in Scala are immutable. If you need mutable lists, Scala provides ListBuffer
, which we'll explore in this lesson.
To create a list in Scala, you can use the List()
function. This will create an immutable list. For mutable lists, you can use ListBuffer
by importing scala.collection.mutable.ListBuffer
:
Scala1import scala.collection.mutable.ListBuffer 2 3@main def run: Unit = 4 val names = List("Alice", "Bob", "Charlie") // An immutable list 5 println(names) // Prints List(Alice, Bob, Charlie) 6 7 val mutableNames = ListBuffer("Alice", "Bob", "Charlie") // A mutable list 8 mutableNames += "Dave" // Adding an element to the mutable list 9 println(mutableNames) // Prints ListBuffer(Alice, Bob, Charlie, Dave)
The import statement import scala.collection.mutable.ListBuffer
is necessary to tell Scala to include the ListBuffer
functionality from its library. Without this, Scala wouldn't recognize ListBuffer
as a valid data structure.
You can access elements in an immutable list using numeric indices. Consider that list indices in Scala start at 0
:
Scala1@main def run: Unit = 2 val fruits = List("Apple", "Banana", "Cherry") 3 println(fruits(0)) // Accessing the first element, "Apple" 4 println(fruits(2)) // Accessing the third element, "Cherry"
Note that index values should be within the range of 0
to list.length - 1
. If you try to access an element with an invalid index, Scala will throw an IndexOutOfBoundsException
:
Scala1@main def run: Unit = 2 val fruits = List("Apple", "Banana", "Cherry") 3 println(fruits) // Prints List(Apple, Banana, Cherry) 4 println(fruits(5)) // This will throw an IndexOutOfBoundsException 5 println(fruits(-3)) // This will throw an IndexOutOfBoundsException
Even though we mentioned that it's not possible to add elements to immutable lists, it's possible to create a new list with additional elements. You can use the :+
or ++
operators to achieve this. These operations will return a new list and keep the original list unchanged:
Scala1@main def run: Unit = 2 val numbers = List(1, 2, 3) 3 println(numbers) // Prints List(1, 2, 3) 4 val moreNumbers = numbers :+ 4 // Appending one element, returns a new list 5 println(moreNumbers) // Prints List(1, 2, 3, 4) 6 val evenMoreNumbers = numbers ++ List(4, 5, 6) // Appending multiple elements, returns a new list 7 println(evenMoreNumbers) // Prints List(1, 2, 3, 4, 5, 6)
To create and modify mutable lists, use ListBuffer
:
Scala1import scala.collection.mutable.ListBuffer 2 3@main def run: Unit = 4 val mutableNames = ListBuffer("Alice", "Bob", "Charlie") // A mutable list 5 println(mutableNames) // Prints ListBuffer(Alice, Bob, Charlie) 6 mutableNames += "Dave" // Adding an element to the mutable list 7 println(mutableNames) // Prints ListBuffer(Alice, Bob, Charlie, Dave)
To add elements to a mutable ListBuffer, you can use +=
for one and ++=
for multiple elements:
Scala1import scala.collection.mutable.ListBuffer 2 3@main def run: Unit = 4 val mutableNumbers = ListBuffer(1, 2, 3) 5 println(mutableNumbers) // Prints ListBuffer(1, 2, 3) 6 mutableNumbers += 4 // Appending one element to the ListBuffer 7 println(mutableNumbers) // Prints ListBuffer(1, 2, 3, 4) 8 mutableNumbers ++= List(5, 6, 7) // Appending multiple elements to the ListBuffer 9 println(mutableNumbers) // Prints ListBuffer(1, 2, 3, 4, 5, 6, 7)
You can modify elements in a ListBuffer using their indices:
Scala1import scala.collection.mutable.ListBuffer 2 3@main def run: Unit = 4 val mutableColors = ListBuffer("Red", "Green", "Blue") 5 println(mutableColors) // Prints ListBuffer(Red, Green, Blue) 6 mutableColors(1) = "Yellow" // Modifies the second element 7 println(mutableColors) // Prints ListBuffer(Red, Yellow, Blue)
And if you want to add elements to an existing List and get a new List as the result instead of changing the original list, you can transition from ListBuffer back to List:
Scala1import scala.collection.mutable.ListBuffer 2 3@main def run: Unit = 4 val mutableNumbers = ListBuffer(1, 2, 3, 4, 5, 6, 7) 5 println(mutableNumbers) // Prints ListBuffer(1, 2, 3, 4, 5, 6, 7) 6 val noMoreMutable = mutableNumbers.toList 7 println(noMoreMutable) // Prints List(1, 2, 3, 4, 5, 6, 7)
Scala Lists come equipped with useful properties that work for both immutable and mutable types. The length
method returns the number of elements, and head
and last
methods refer to the first and last elements, respectively:
Scala1@main def run: Unit = 2 val numbers = List(1, 2, 3, 4, 5) 3 println(numbers.length) // Size of the list, prints 5 4 5 val colors = List("Red", "Green", "Blue") 6 println(colors.head) // First element, prints "Red" 7 println(colors.last) // Last element, prints "Blue"
Additionally, the size
method also returns the number of elements in the list, similar to length
. The isEmpty
method checks if the list is empty, returning true
if it is and false
otherwise. The contains
method checks if a certain element exists in the list:
Scala1@main def run: Unit = 2 val items = List("Pen", "Book", "Notebook") 3 println(items.size) // 3 4 println(items.isEmpty) // false 5 println(items.contains("Book")) // true 6 println(items.contains("Pencil")) // false
In Scala, both arrays and lists are used to store collections of elements, but they serve different purposes and have different characteristics.
Mutability:
ListBuffer
.Performance:
Usage:
ListBuffer
.Understanding the difference between arrays and lists will help you choose the appropriate data structure based on your needs.
Congratulations! You've unravelled Lists in Scala today, uncovering their essence, learning how to create and manipulate them, and understanding their properties. Next, we will put these knowledge points into practice. The upcoming practice will help you cement these concepts and refine your programming skills further. See you soon in the exciting world of Scala!