📜  在 Kotlin 中实现惰性列表

📅  最后修改于: 2022-05-13 01:54:49.512000             🧑  作者: Mango

在 Kotlin 中实现惰性列表

如果一个元素或表达式的值在定义时没有被计算,而是在它第一次被访问时被计算,则称它为惰性计算。在很多情况下它都能派上用场。例如,你可能有一个列表 A,你想从它创建一个过滤列表,我们称之为列表 B。如果你做如下的事情,过滤操作将在 B 的声明期间执行。

这迫使程序在定义 B 后立即对其进行初始化。虽然这对于一个小列表来说可能没什么大不了的,但它可能会导致较大对象的延迟。此外,我们可以延迟对象创建,直到我们第一次需要它。在这个秘籍中,我们将学习如何实现惰性列表。

例子

要创建惰性列表,我们需要将列表转换为序列。一个序列代表惰性求值的集合。让我们通过一个例子来理解它:

1. 在给定的示例中,我们首先根据元素的奇数或偶数过滤列表:

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


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


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


输出:

Testing 1
Testing 2
Testing 3
Testing 4

在前面的示例中,仅在定义对象时才评估过滤器函数

2. 现在,让我们将列表转换为序列。将列表转换为序列仅一步之遥;您可以将任何列表转换为序列

使用.asSequence()方法,或通过Sequence { createIterator() }:

科特林

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

3. 如果你运行前面的代码,你不会在控制台看到任何输出,因为对象还没有被创建。它将在首次访问列表 B 时创建:

科特林

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

输出:

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

访问项目时评估过滤器函数。这称为惰性求值。

Kotlin 中的序列可能是无界的,并且在事先不知道列表长度时使用。由于它可以是无限的,因此这种类型的结构需要惰性求值。考虑这个例子:

在这里, generateSequence生成一个无限数的序列,但是当我们调用take(10)时,只有 10 个项目被评估和打印。