
A class for immutable linked lists representing ordered collections of elements of type. This class comes with two implementing case classes last-in-first-out (
LIFO
)
stack-like access patterns.
Given below are a few examples
val myList = List(3, 2, 1)
myList: List[Int] = List(1, 2, 3, 4)
val myListwith4 = 4 :: myList // re-uses mainList
myList4: List[Int] = List(4, 1, 2, 3, 4)
val myList42 = 42 :: myList4
myList42: List[Int] = List(42,4, 1, 2, 3, 4) //also re-uses
val myListtail = MyList42.tail // tail previous list
mylisttail: List[Int] = List(4, 1, 2, 3, 4)
Lists are immutable, they behave like Java strings, when you call a method on a list that might seem by its name to imply the list will mutate, it instead
creates and returns a new list with the new value. For example, List has a method named `:::’ for list concatenation.
Here’s how you use it:
val oneTwo = List(1, 2)
oneTwo: List[Int] = List(1, 2)
val threeFour = List(3, 4)
threeFour: List[Int] = List(3, 4)
val oneTwoThreeFour = oneTwo ::: threeFour
oneTwoThreeFour: List[Int] = List(1, 2, 3, 4)
oneTwoThreeFour
res1:List[Int] = List(1, 2, 3, 4)
Different ways to create a List
You can create a Scala List in several different ways. 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.
Basic Methods
The ‘head’ method
scala> val a:List[Int]=List(1,3,2) a: List[Int] = List(1, 3, 2)
scala> a.head res13: Int = a
The ‘tail’ method
This returns the last element of a Scala list.
scala> a.tail
res14: List[Int] = List(2,3)
The ‘isEmpty’ method
If the list is empty, this returns a Boolean true; otherwise, false.
scala> val a:List[Int]=List(1,3,2) a: List[Int] = List(1, 3, 2)
scala> a.isEmpty
res15: Boolean = false
The ‘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 ‘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)
Concatenating Lists in Scala
We can join or concatenate two Scala lists in one of three ways. Let’s take two lists for this:
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)
The ::: Operator
scala> a:::b
res0: List[Int] = List(1, 2, 3, 4, 5, 6)
The List.:::() Method
We can call the :::() method on the first list.
scala> a.:::(b)
res2: List[Int] = List(4, 5, 6, 1, 2, 3)
scala> a
res3: List[Int] = List(1, 2, 3)
The List.concat() Method
We can also call the concat() method on List in Scala Collections. We pass both the lists as arguments.
scala> List.concat(a,b)
res5: List[Int] = List(1, 2, 3, 4, 5, 6)
Tabulating a Function
Using the List.tabulate() method with a function, we can tabulate a Scala list. The first argument specifies the dimensions; the second describes the elements(computed from a function).
scala> val g=List.tabulate(7)(n=>n*2)
g: List[Int] = List(0, 2, 4, 6, 8, 10, 12)
We can also pass more than one size argument Reversing a Scala List:
scala> val h=List.tabulate(3,7)(_*_)
h: List[List[Int]] = List(List(0, 0, 0, 0, 0, 0, 0), List(0, 1, 2, 3, 4, 5, 6), List(0, 2, 4, 6, 8, 10, 12))
Reversing a Scala List
This reverses the order of elements in a list using the List.reverse method.
scala> list
res6: List[Int] = List(1, 2, 3)
scala> list.reverse
res7: List[Int] = List(3, 2, 1)
scala> list
res8: List[Int] = List(1, 2, 3)
As you can see in above example that the reverse function is not making any modification in our List a, if we want to store reverse list somewhere, we have to store it in any variable.
Foreach: Iteration of Lists
A very common way to iterate on Scala lists foreach
Here’s an example showing how to use the foreach function to print every item in a List:
scala> val mylist = List(1,2,3)
mylist: List[Int] = List(1, 2, 3)
scala> mylist.foreach { println }
1
2
3
Here is an example to calculate sum of all the elements in list using
scala> var sum = 0
sum: Int = 0
scala> val mylist = List(1,2,3)
mylist: List[Int] = List(1, 2, 3)
scala> mylist.foreach(sum += _)
scala> println(sum)
6
Filtering the scala List
The filter
method is used to filter any list’s elements through any conditions like in below example :, we filter the list by selecting
scala> val mylist = List(1,2,3,4,5,6,7)
mylist: List[Int] = List(1, 2, 3, 4, 5, 6, 7)
scala> val evenElements = mylist.filter(a => a % 2 == 0)
evenElements: List[Int] = List(2, 4, 6)
take while
The takeWhile
condition is same, lets have a look at below example :
scala> val mylist = List(1,2,3,4,5,6,7)
mylist: List[Int] = List(1, 2, 3, 4, 5, 6, 7)
scala> val mylist1 = mylist.takeWhile(a => a < 6) y: List[Int] = List(1, 2, 3, 4, 5)
The List map function
The map function in scala used to transform all the elements of an list based on any defined function.
scala> val mylist = List(1,2,3)
mylist: List[Int] = List(2,3,4)
scala> val mappedlist = x.map(a => a * 2)
mappedlist: List[Int] = List(4,6,8)
using the Scala wildcard character (_) instead of a new variable name:
scala> val mylist = x.map(_ * 2)
mylist: List[Int]
Here are some other examples of List mapping
scala> val namelist = List("shubham", "azmat", "sakshi")
namelist: List[java.lang.String] = List(Shubham, Azmat, Sakshi)
scala> val lowerlist = namelist.map(_.toLowerCase)
lowerlist: List[java.lang.String] = List(shubham, azmat,sakshi)
scala> val upperlist = names.map(_.toUpperCase)
upperlist: List[java.lang.String] = List(SHUBHAM, AZMAT, SAKSHI)
The List flatMap function
Now, let’s move on to flatMap(), so as the name signifies flatMap() flatten the hierarchy level by one level each time it is applied. A flatMap method also takes a function but, the function in this case returns a sequence. The flatMap() operation flattens the result in the resultant list, it applies that function to each element
scala> val list = List(1, 2, 3, 4)
list: List[Int] = List(1, 2, 3, 4)
scala> val addUnity = (x: Int) => List(x *2, x - 1)
addUnity: Int => List[Int] = <function1>
scala> list.flatMap(addUnity)
res3: List[Int] = List(2, 0, 4, 1, 6, 2, 8, 3)
map vs flatMap function
now let’s see what happens when we apply map() and flatMap() operations…
scala> list.flatMap(addUnity)
res3: List[Int] = List(2, 0, 4, 1, 6, 2, 8, 3)
scala> list.map(addUnity)
res4: List[List[Int]] = List(List(2, 0), List(4, 1), List(6, 2), List(8, 3))
This is the difference between an map and flatMap function , an map function gives you an List of List and flatmap maps all the elements , applied function on them and flattened the List.
Methods on a List in Scala
We can also call the following methods on a Scala List: (Note that these don’t modify the Lists)
a. def +(elem: A): List[A]
This postpends an element to the Scala list.
scala> a.+("2")
res12: String = List(1, 2, 3)2
b. def addString(b: StringBuilder): StringBuilder
This appends all elements of a Scala list to a String Builder.
scala> var b=new StringBuilder()
b: StringBuilder =
scala> a.addString(b)
res19: StringBuilder = 123
scala> a
res20: List[Int] = List(1, 2, 3)
scala> b
res21: StringBuilder = 123
c. def addString(b: StringBuilder, sep: String): StringBuilder
This does the same thing, except with a separator between the elements.
Let’s first reset b to an empty string.
scala> b=new StringBuilder()
b: StringBuilder =
scala> a.addString(b,"*")
res23: StringBuilder = 1*2*3
d. def apply(n: Int): A
This selects an element in the Scala List by its index.
scala> a.apply(2)
res24: Int = 3
e. def contains(elem: Any): Boolean
If the list contains a certain element, this returns true; otherwise, false.
scala> a.contains(2)
res25: Boolean = true
scala> a.contains(4)
res26: Boolean = false
f. def drop(n: Int): List[A]
This returns all elements except the first n.
scala> var j=List(1,1,4,1,3,2,1)
j: List[Int] = List(1, 1, 4, 1, 3, 2, 1)
scala> j.drop(2)
res27: List[Int] = List(4, 1, 3, 2, 1)
g. def dropRight(n: Int): List[A]
This returns all elements except the last n.
scala> j.dropRight(2)
res28: List[Int] = List(1, 1, 4, 1, 3)
h. def distinct: List[A]
Distinct returns a new List without duplicates.
scala> j.distinct
res29: List[Int] = List(1, 4, 3, 2)
i. def init: List[A]
This returns all elements except the last.
scala> a.init
res30: List[Int] = List(1, 2)
j. def length: Int
This returns a List’s length.
scala> a.length
res31: Int = 3
k. def max: A
This returns the highest element.
scala> a.max
res32: Int = 3
l. def min: A
This returns the lowest element.
scala> a.min
res33: Int = 1
m. def mkString: String
This displays all elements of a list in a String.
scala> a.mkString
res34: String = 123
n. def flatten: List[A]
Use the flatten
method to convert a list of lists into a single list. To demonstrate this, first create a list of lists:
scala> val list = List(List(1,2), List(3,4))
list: List[List[Int]] = List(List(1, 2), List(3, 4))
Calling the flatten
method on this list of lists creates one new list:
list.flatten
res0: List[Int] = List(1, 2, 3, 4)
flatten
does what its name implies, flattening the lists held inside the outer list into one resulting list
o. def sum: A
This returns the sum of all elements.
scala> a.sum
res36: Int = 6
p. def equals(that: Any): Boolean
This compares two sequences.
scala> a.equals(b)
res53: Boolean = false
scala> a.equals(List(1,2,3))
res55: Boolean = true
q. def toArray: Array[A]
This returns an Array from a List.
scala> a.toArray
res37: Array[Int] = Array(1, 2, 3)
References :