Table of Contents
- Introduction
- Scala List class: Introduction
- Creating an instance of a Scala List
- The List ‘range’ method
- The List ‘fill’ method
- The List class ‘tabulate’ method
- How to prepend items to a Scala List
- Appending and merging Lists
- Iterating Scala lists with foreach
- Scala Lists and the ‘for’ expression
- Filtering Scala lists
- The List ‘map’ function
- Sorting Scala Lists
- Scala List class and pattern matching
- Other Scala List functions
- Relatives of the Scala List
- Scala first-order and higher-order functions
- Summary: Scala List class examples
Scala List
FAQ: Can you share some Scala List
class examples, such as how to create and use the Scala List
class and its methods?
Introduction
The Scala List class may be the most commonly used data structure in Scala applications. Therefore, it's very helpful to know how create lists, merge lists, select items from lists, operate on each element in a list, and so on.
In this tutorial, I'll share examples of the most common List
operations (methods).
Scala List class: Introduction
The Scala List
class — scala.List — holds a sequenced, linear list of items. In a List
, each element must be of the same type (or at least the same base type).
At some point I'll add a class diagram here, but until then, here's a simplified version of the Scala List
class hierarchy:
- The scala.List class is a pointer to the scala.collection.immutable.List class
- The
List
class extends LinearSeq with Product (and some others) - The trait LinearSeq extends Seq
- The trait Seq extends Iterable
- Iterable extends trait Traversable
(I need to update this, but this is the Scala class hierarchy, as shown by the current Scala API documentation.
Creating an instance of a Scala List
You can create a Scala List
object in several different way. Here's the Lisp-style approach to creating a List
:
scala> val list = 1 :: 2 :: 3 :: Nil list: List[Int] = List(1, 2, 3)
Here's the Java-style approach to creating a Scala List:
scala> val list = List(1,2,3) x: List[Int] = List(1, 2, 3)
A few notes about these approaches:
- The first approach shows the "cons" syntax, which, as I mentioned, is the Lisp style of creating a list.
- The :: method takes two arguments, a "head", which is a single element, and a "tail", which is a
List
. - As you can see, Scala can usually infer the type of a
List
very well.
If you're mixing types in a List
constructor, you may need to manually specify the List
type. This example demonstrates that syntax:
scala> val x = List[Number](1, 2.0, 33d, 0x1) x: List[java.lang.Number] = List(1, 2.0, 33.0, 1)
In this example, I'm explicitly saying that I want the values in the List
to be saved as the Number
type.
The List ‘range’ method
You can also create a List
with its range
method:
scala> val x = List.range(1,10) x: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
The range function can also take a third argument which serves as a "step" value when creating the List
:
scala> val x = List.range(0,10,2) x: List[Int] = List(0, 2, 4, 6, 8)
The List ‘fill’ method
You can also create a new List
with its fill method:
scala> val x = List.fill(3)("foo") x: List[java.lang.String] = List(foo, foo, foo)
The List class ‘tabulate’ method
Finally, you can create a new List
with the tabulate method of the List class. The tabulate method creates a new List
whose elements are created according to the function you supply. The book Programming in Scala shows how to create a List
using a simple "squares" function:
scala> val x = List.tabulate(5)(n => n * n) x: List[Int] = List(0, 1, 4, 9, 16)
As you can see, that example creates a List of five elements, where the element values are the square of the index of each element (0 becomes 0, 1 becomes 1, 2 becomes 4, 3 becomes 9, and 4 becomes 16).
In summary, you can create a new Scala List with these approaches:
- Lisp style
- Java style
- range method
- tabulate method
How to prepend items to a Scala List
You can prepend items to a Scala List
using the ::
method:
// create a List scala> val x = List(1,2,3) x: List[Int] = List(1, 2, 3) // prepend an element to the list scala> val y = 0 :: x y: List[Int] = List(0, 1, 2, 3)
According to the Beginning Scala book (and several other sources), prepending items to a list is a "very fast, constant-time, O(1) operation."
(Again, I recall this approach and syntax from using Lisp many years ago.)
Appending and merging Lists
There are at least two ways to merge Scala Lists. First, you can merge two Scala lists using the ::: method of the List class:
scala> val a = List(1,2,3) a: List[Int] = List(1, 2, 3) scala> val b = List(4,5,6) b: List[Int] = List(4, 5, 6) scala> val c = a ::: b c: List[Int] = List(1, 2, 3, 4, 5, 6)
This operation is said to have O(n) speed, where n is the number of elements in the first List.
You can also merge two Scala lists using the List's concat method:
scala> val a = List(1,2,3) a: List[Int] = List(1, 2, 3) scala> val b = List(4,5,6) b: List[Int] = List(4, 5, 6) scala> val c = List.concat(a, b) c: List[Int] = List(1, 2, 3, 4, 5, 6)
Iterating Scala lists with foreach
A very common way to iterate over Scala lists is with the foreach method. Here's a quote about the foreach
method from the book Programming in Scala:
foreach
takes a procedure (a function with a result typeUnit
) as the right operand. It simply applies the procedure to eachList
element. The result of the operation is againUnit
; no list of results is assembled.
Here's a simple example showing how to use the foreach
method to print every item in a List
:
scala> val x = List(1,2,3) x: List[Int] = List(1, 2, 3) scala> x.foreach { println } 1 2 3
This next example shows a way to sum all the elements in a list using the foreach
method:
scala> var sum = 0 sum: Int = 0 scala> val x = List(1,2,3) x: List[Int] = List(1, 2, 3) scala> x.foreach(sum += _) scala> println(sum) 6
Scala Lists and the ‘for’ expression
The Scala for expression is not specific to lists, but is an extremely powerful way to operate on lists. Here's a simple example of how to iterate over a list using the for expression:
scala> val names = List("Bob", "Fred", "Joe", "Julia", "Kim") names: List[java.lang.String] = List(Bob, Fred, Joe, Julia, Kim) scala> for (name <- names) println(name) Bob Fred Joe Julia Kim
So far, so good. Now let's add a simple "if" clause to the for expression to print only the elements we want to print:
scala> val names = List("Bob", "Fred", "Joe", "Julia", "Kim") names: List[java.lang.String] = List(Bob, Fred, Joe, Julia, Kim) scala> for (name <- names if name.startsWith("J")) | println(name) Joe Julia
If you already know about the for expression, you know that you can add multiple if clauses, and much more functionality. I could easily write an entire tutorial on the Scala for comprehension, so to keep this tutorial short, I'll stop here for now.
Before leaving, I will add these notes however, from the book Programming in Scala:
Scala provides the for comprehension, which provides syntactically pleasing nesting of map, flatMap, and filter ... The for comprehension is not a looping construct, but is a syntactic construct the compiler reduces to map, flatMap, and filter.
Filtering Scala lists
A great thing about Scala is that it is a functional programming language. In the next examples we'll show some of the power of functional programming. In this section we'll focus on the filter method of the List class.
scala> val x = List(1,2,3,4,5,6,7,8,9,10) x: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) // create a list of all the even numbers in the list scala> val evens = x.filter(a => a % 2 == 0) evens: List[Int] = List(2, 4, 6, 8, 10)
takeWhile
scala> val x = List(1,2,3,4,5,6,7,8,9,10) x: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) scala> val y = x.takeWhile(a => a < 6) y: List[Int] = List(1, 2, 3, 4, 5)
Other list filtering methods:
partition - returns a pair of lists, one where the predicate is true, the other where the predicate is false find - returns the first element matching a predicate (as opposed to returning all such elements) Others: takeWhile, dropWhile, span
The List ‘map’ function
The Scala List map function "transforms each element of a collection based on a function."
Here are a few map examples. First, doubling every item in a List:
scala> val x = List(1,2,3) x: List[Int] = List(1, 2, 3) scala> val y = x.map(a => a * 2) y: List[Int] = List(2, 4, 6)
Here's a slightly simpler version of that map example, using the Scala wildcard character (_) instead of a fake variable name:
scala> val y = x.map(_ * 2) y: List[Int] = List(2, 4, 6)
Here's an example using a list of strings:
scala> val names = List("Fred", "Joe", "Bob") names: List[java.lang.String] = List(Fred, Joe, Bob) scala> val lower = names.map(_.toLowerCase) lower: List[java.lang.String] = List(fred, joe, bob) scala> val upper = names.map(_.toUpperCase) upper: List[java.lang.String] = List(FRED, JOE, BOB)
A very nice example in the book Beginning Scala demonstrates how to convert a List into something useful in the HTML world, a list of <li> elements using the map function:
scala> val names = List("Fred", "Joe", "Bob") names: List[java.lang.String] = List(Fred, Joe, Bob) scala> val li = names.map(name => <li>{name}</li>) li: List[scala.xml.Elem] = List(<li>Fred</li>, <li>Joe</li>, <li>Bob</li>)
As you can see, you can rapidly build a lot of functionality in just a little bit of code.
Sorting Scala Lists
I need to research why this code is deprecated, but for the time being, here's an example of how to sort a Scala List:
scala> val x = List(10, 2, 5) x: List[Int] = List(10, 2, 5) scala> val y = x.sort(_ < _) warning: there were 1 deprecation warnings; re-run with -deprecation for details y: List[Int] = List(2, 5, 10)
(TODO: Research the correct, current approach for sorting Scala lists.)
Scala List class and pattern matching
You can use the List class with the Scala pattern matching and case/match syntax. I'll add examples here as I create them in my own code. (TODO)
Other Scala List functions
The Scala List class has an incredible number of functions/methods, and over time I'll attempt to document them all. In the meantime, here's a short list of the many other Scala List methods I don't have examples for at this time:
length - returns the length of a List head - returns the first element of a List last - returns the last element of a List init - returns a List consisting of all elements except the last one tail - returns every elements of a List except the first element isEmpty - returns a Boolean indicating if the List is empty reverse - returns a reversed version of the List flatten - takes a list of lists and flattens it out to a single list mkString - converts a List to a String iterator toArray foldLeft reduceLeft map flatMap foreach forall exists Folding lists: /: and :\ sortWith
Again, I'll try to add examples of these List methods over time. (TODO)
Relatives of the Scala List
There are times you may want to use one of the relatives of the Scala List class, instead of using the List class itself. I'll add more to this over time, but for now, here are a few links:
- The ListBuffer class
- The MutableList class
Scala first-order and higher-order functions
On a slightly related note, functional programming languages describe functions as being either first-order, or higher-order. Here are definitions for these terms:
A Scala method is first-order if it does not take any functions as arguments.
and:
Higher-order functions are functions that take other functions as parameters.
Summary: Scala List class examples
I hope these Scala List class examples have been helpful. I've tried to show at least one example for each important Scala List method, and I'll try to add many more examples as time goes on.
Update: For dozens of additional examples, see my Scala List class methods, examples, and syntax page.
In functional programming languages, the concept of a list class is very important, and as you can see, this leads to an incredible wealth of methods/functions that are available on the Scala List class.