Kotlin-确保在开始下一个收集操作之前完成收集操作
如果需要,请编写以下代码:Kotlin-确保在开始下一个收集操作之前完成收集操作,kotlin,collections,sequence,Kotlin,Collections,Sequence,如果需要,请编写以下代码: fun main(args: Array<String>) { val letters = listOf("a", "b", "c", "d") letters.map { print(it); it }.forEach { print(it) } } 我得到以下信息:aabbccdd Kotlin的序列似乎不能保证“组操作”(例如map或forEach)在其他操作开始之前完成,但当我们将这些操作应用于集合时,可以保证操作一次完成一个 在
fun main(args: Array<String>) {
val letters = listOf("a", "b", "c", "d")
letters.map { print(it); it }.forEach { print(it) }
}
我得到以下信息:aabbccdd
Kotlin的序列似乎不能保证“组操作”(例如map
或forEach
)在其他操作开始之前完成,但当我们将这些操作应用于集合时,可以保证操作一次完成一个
在开始执行下一个链式“组操作”之前,我们如何保证将对集合或序列中的所有元素应用“组操作”,如map
或forEach
在开始执行下一个链式“组操作”之前,我们如何保证“组操作”如map或forEach将应用于集合或序列中的所有元素
行为取决于输入是集合
还是序列
- 集合将对集合中的每个元素应用链中的单个操作,然后再应用链中的下一个操作。这就是为什么您会看到一次
,然后再次看到“abcd”
“abcd”
- 序列将链中的每个操作应用于序列中的每个元素,然后再将所有操作应用于序列中的下一个元素。这就是为什么您会看到
,然后看到“aa”
,等等“bb”
序列
(例如通过映射
或其他函数),该变换也会被延迟应用。只有当您实际计算序列中的元素时(在您的例子中,这是由forEach
)才会应用转换
如果需要序列中的集合
行为,则必须首先将序列转换为集合。您可以调用sequence.toList()
或以其他方式对其进行转换,但无法从现成的序列中获得“急切”行为
让我们浏览两种不同的场景
当字母
是列表时
列表不是懒惰的。为了将一个列表映射到另一个列表,我们必须遍历整个输入列表,转换每个元素,并构建输出列表。考虑到这一点
第一个操作,map{print(it);it}
,从输入中读取每个值,打印它,并创建一个新列表。它返回一个列表,其中包含“a”、“b”、“c”、“d”
,程序已打印“abcd”
第二个操作,forEach{print(it)}
,迭代列表并打印每个元素。此操作完成后,程序将再次打印“abcd”
,总输出为“abcdabcd”
当字母
是序列
序列是懒惰的。为了将一个序列映射到另一个序列,程序保留转换方法,并等待其他人实际需要值后再执行转换。所以
第一个操作创建一个新的TransformingSequence
,它保存原始序列和打印(它);将其返回变压器。它返回这个新序列,程序还没有打印任何内容
第二个操作是“终端”(即,它实际计算序列中的每个元素)。它遍历序列并打印每个元素。但是请记住:我们迭代的序列是一个TransformingSequence
,它本身打印每个元素!因此,forEach
调用中的第一个print
操作打印“aa”
,第二个打印“bb”
,依此类推,总输出为“aabbccdd”
fun main(args: Array<String>) {
val letters = listOf("a", "b", "c", "d")
letters.asSequence().map { print(it); it }.forEach { print(it) }
}