# Scala Collections - List

Scala Lists are quite similar to arrays which means, all the elements of a list have the same type but there are two important differences. First, lists are immutable, which means elements of a list cannot be changed by assignment. Second, lists represent a linked list whereas arrays are flat.

The type of a list that has elements of type T is written as List[T].

Try the following example, here are few lists defined for various data types.

```// List of Strings
val fruit: List[String] = List("apples", "oranges", "pears")
// List of Integers
val nums: List[Int] = List(1, 2, 3, 4)
// Empty List.
val empty: List[Nothing] = List()
// Two dimensional list
val dim: List[List[Int]] = List(
List(1, 0, 0),
List(0, 1, 0),
List(0, 0, 1)
)
```

All lists can be defined using two fundamental building blocks, a tail Nil and ::, which is pronounced cons. Nil also represents the empty list. All the above lists can be defined as follows.

```// List of Strings
val fruit = "apples" :: ("oranges" :: ("pears" :: Nil))
// List of Integers
val nums = 1 :: (2 :: (3 :: (4 :: Nil)))
// Empty List.
val empty = Nil
// Two dimensional list
val dim = (1 :: (0 :: (0 :: Nil))) ::
(0 :: (1 :: (0 :: Nil))) ::
(0 :: (0 :: (1 :: Nil))) :: Nil
```

## Basic Operations on Lists

All operations on lists can be expressed in terms of the following three methods.

Sr.No Methods & Description
1

This method returns the first element of a list.

2

tail

This method returns a list consisting of all elements except the first.

3

isEmpty

This method returns true if the list is empty otherwise false.

The following example shows how to use the above methods.

### Example

```object Demo {
def main(args: Array[String]) {
val fruit = "apples" :: ("oranges" :: ("pears" :: Nil))
val nums = Nil
println( "Tail of fruit : " + fruit.tail )
println( "Check if fruit is empty : " + fruit.isEmpty )
println( "Check if nums is empty : " + nums.isEmpty )
}
}
```

Save the above program in Demo.scala. The following commands are used to compile and execute this program.

### Command

```\>scalac Demo.scala
\>scala Demo
```

### Output

```Head of fruit : apples
Tail of fruit : List(oranges, pears)
Check if fruit is empty : false
Check if nums is empty : true
```

## Concatenating Lists

You can use either ::: operator or List.:::() method or List.concat() method to add two or more lists. Please find the following example given below −

### Example

```object Demo {
def main(args: Array[String]) {
val fruit1 = "apples" :: ("oranges" :: ("pears" :: Nil))
val fruit2 = "mangoes" :: ("banana" :: Nil)
// use two or more lists with ::: operator
var fruit = fruit1 ::: fruit2
println( "fruit1 ::: fruit2 : " + fruit )
// use two lists with Set.:::() method
fruit = fruit1.:::(fruit2)
println( "fruit1.:::(fruit2) : " + fruit )
// pass two or more lists as arguments
fruit = List.concat(fruit1, fruit2)
println( "List.concat(fruit1, fruit2) : " + fruit  )
}
}
```

Save the above program in Demo.scala. The following commands are used to compile and execute this program.

### Command

```\>scalac Demo.scala
\>scala Demo
```

### Output

```fruit1 ::: fruit2 : List(apples, oranges, pears, mangoes, banana)
fruit1.:::(fruit2) : List(mangoes, banana, apples, oranges, pears)
List.concat(fruit1, fruit2) : List(apples, oranges, pears, mangoes, banana)
```

## Creating Uniform Lists

You can use List.fill() method creates a list consisting of zero or more copies of the same element. Try the following example program.

### Example

```object Demo {
def main(args: Array[String]) {
val fruit = List.fill(3)("apples") // Repeats apples three times.
println( "fruit : " + fruit  )
val num = List.fill(10)(2)         // Repeats 2, 10 times.
println( "num : " + num  )
}
}
```

Save the above program in Demo.scala. The following commands are used to compile and execute this program.

### Command

```\>scalac Demo.scala
\>scala Demo
```

### Output

```fruit : List(apples, apples, apples)
num : List(2, 2, 2, 2, 2, 2, 2, 2, 2, 2)
```

## Tabulating a Function

You can use a function along with List.tabulate() method to apply on all the elements of the list before tabulating the list. Its arguments are just like those of List.fill: the first argument list gives the dimensions of the list to create, and the second describes the elements of the list. The only difference is that instead of the elements being fixed, they are computed from a function.

Try the following example program.

### Example

```object Demo {
def main(args: Array[String]) {
// Creates 5 elements using the given function.
val squares = List.tabulate(6)(n => n * n)
println( "squares : " + squares  )
val mul = List.tabulate( 4,5 )( _ * _ )
println( "mul : " + mul  )
}
}
```

Save the above program in Demo.scala. The following commands are used to compile and execute this program.

### Command

```\>scalac Demo.scala
\>scala Demo
```

### Output

```squares : List(0, 1, 4, 9, 16, 25)
mul : List(List(0, 0, 0, 0, 0), List(0, 1, 2, 3, 4),
List(0, 2, 4, 6, 8), List(0, 3, 6, 9, 12))
```

## Reverse List Order

You can use List.reverse method to reverse all elements of the list. The Following example shows the usage.

### Example

```object Demo {
def main(args: Array[String]) {
val fruit = "apples" :: ("oranges" :: ("pears" :: Nil))
println( "Before reverse fruit : " + fruit )
println( "After reverse fruit : " + fruit.reverse )
}
}
```

Save the above program in Demo.scala. The following commands are used to compile and execute this program.

### Command

```\>scalac Demo.scala
\>scala Demo
```

### Output

```Before reverse fruit : List(apples, oranges, pears)
After reverse fruit : List(pears, oranges, apples)
``` 