### Kotlin Collections vs Sequences in just 5minutes

Let’s understand the difference between Collections and Sequences with a simple example:

`val operations = (1..10)    .filter{it % 2 == 1}    .map { it * 2 }    .take(2)`

### Collections

In the above collection operations, we first loop through numbers from 1 to 10, then create a collection of numbers who are odd, then create another collection by multiplying the elements of previous collection by 2 and then create a collection by taking first 2 elements of previous collection.

For the above example with collections, the results at each step would be as follows:

`val operations = (1..10)     .filter { it % 2 == 1 } // 1, 3, 5, 7, 9    .map { it * 2 }        // 2, 6, 10, 14, 18    .take(2)               // 2, 6`

Now, let’s take a look at the map function for Collections.

`public inline fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R> {    return mapTo(ArrayList<R>(collectionSizeOrDefault(10)), transform)}`

As you can see here, map function for collections is an inline function, that takes in a collection and returns another collection.

So, collections are,

1. Evaluated eagerly.
This means, all the operations applied on the collection are always evaluated and they are evaluated in the same order as they are applied.

2. Each transformation is performed on the entire collection.

3. A new collection gets created after applying transformation on the initial collection.

4. Suitable for smaller lists, not for larger ones as processing intermediate collection equation becomes expensive.

### Sequences

Now, let’s understand the above through sequences.

We can convert a collection to sequence using the asSequence() function, so the above code can be written as follows:

`val operations = (1..10).asSequence()    .filter{it % 2 == 1}    .map { it * 2 }    .take(2)    .toList()`

In the above sequence, we will first loop through numbers from 1 to 10, then look at each element one by one, then put the filter transformation, which is an an intermediate operation into the list of operations to be performed by the sequence, but the filter operation isn’t performed, same for map operation, once we encounter the terminal operation, which is ‘take’ operator in this case, all the transformations are applied

For the above code snippet, the following operations would be performed for a sequence.

Now, let’s have a look at the map function for sequences.

`public fun <T, R> Sequence<T>.map(transform: (T) -> R): Sequence<R> {    return TransformingSequence(this, transform)}`

The map function for sequences doesn’t create a new collection, instead it creates a TransformingSequence that holds the transformation function.

So, sequences are,

1. Evaluated lazily, that is, on a need basis, based on the terminal operation.

2. Each transformation is performed on the element-by-element.

3. No new collection is created.

4. Suitable for larger lists.