Open In App

Implement Lazy List in Kotlin

Last Updated : 03 Jan, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

If the value of an element or expression is not evaluated when it’s defined, but rather when it is first accessed, it is said to be lazily evaluated. There are many situations where it comes in handy. For example, you might have a list A and you want to create a filtered list from it, let’s call it list B. If you do something like the following, the filter operation will be performed during the declaration of B.

val A = listOf(1,2,3,4)

var B= A.filter { it%2==0 }

This forces the program to initialize B as soon as it is defined. While this may not be a big deal for a small list, it can cause latency with bigger objects. Also, we can delay the object creation until we first need it. In this recipe, we will learn how we can implement a lazy list.

Example

To create a lazy list, we need to convert the list into a sequence. A sequence represents lazily evaluated collections. Let’s understand it with an example:

1. In the given example, let’s first filter a list based on elements being odd or even:

Kotlin




fun main(args: Array<String>) {
   val A= listOf(1,2,3,4)
   var B=A.filter {
           println ("Testing ${it}")
        it%2==0
   }
}


Output:

Testing 1
Testing 2
Testing 3
Testing 4

In the preceding example, the filter function was evaluated only when the object was defined

2. Now, let’s convert the list into a sequence. Converting the list to a sequence is just one step away; you can convert any list to a sequence 

using the .asSequence()  method, or by Sequence { createIterator() }:

Kotlin




fun main(args: Array<String>) {
  val A = listOf(1,2,3,4).asSequence()
  var B = A.filter{
    println("testing ${it}")
    it%2==0
  }
}


3. If you run the preceding code, you won’t see any output in the console, because, the object hasn’t been created yet. It will be created when list B is first accessed:

Kotlin




fun main(args: Array<String>) {
  val A = listOf(1,2,3,4).asSequence()
  var B = A.filter{
    println("testing  ${it}")
    it%2==0
  }
  B.forEach{
      println("printing ${it}")
  }
}


Output:

 testing  1
 testing  2
 printing 2
 testing  3
 testing  4
 printing 4

The filter function was evaluated when the items were accessed. This is called lazy evaluation.

Sequences in Kotlin are potentially unbounded and are used when the length of the list is not known in advance. Since it can be infinite, lazy evaluation is needed for this type of structure. Consider this example:

val seq = generateSequence(1) { it* 2 }

seq.take(10).forEach { print (” ${it} “) }

Here, generateSequence generates a sequence of infinite numbers, but when we call take(10), only 10 items are evaluated and printed.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads