- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如何迭代地“取(N)”——得到一个序列
我正在用 Kotlin 编写高负载应用程序。
我有数以万计的条目要插入到数据库中。
我想以 1000 个为单位对它们进行批处理。
所以我创建了一个循环:
val itemsSeq = itemsList.iterator().asSequence()
while (true) {
log.debug("Taking $BATCH_SIZE from $itemsSeq")
val batchSeq = itemsSeq.take(BATCH_SIZE)
val squareBatch = applySomething(batchSeq, something)
?: break
}
fun applySomething(batch: Sequence<Item>, something: Something) {
/* Fully consumes batch. Bulk-loads from DB by IDs, applies, bulk-saves. */
}
我认为 take()
会推进 itemsSeq
并且下一次调用 take()
会给我一个序列“ View ” itemsSeq
从第 10 个项目开始。
但是使用这段代码,我得到:
DEBUG Taking 10 from kotlin.sequences.ConstrainedOnceSequence@53fe15ff
Exception in thread "main" java.lang.IllegalStateException: This sequence can be consumed only once.
at kotlin.sequences.ConstrainedOnceSequence.iterator(SequencesJVM.kt:23)
at kotlin.sequences.TakeSequence$iterator$1.<init>(Sequences.kt:411)
at kotlin.sequences.TakeSequence.iterator(Sequences.kt:409)
所以看起来 take()
再次“打开”itemsSeq
,而它只能消耗一次。
作为解决方法,我可以使用 chunked()
:
public fun <T> Sequence<T>.chunked(size: Int): Sequence<List<T>> {
但我宁愿不创建List
,而是创建Sequence
。
我正在寻找的是 take()
和 chunked()
之间的东西。
Kotlin SDK中有这样的东西吗?
我可以创建自己的 sequence { ... }
但为了可读性,我更喜欢内置的东西。
最佳答案
有一种方法可以通过将序列传递给迭代器来构造序列,请参阅 Sequence .
Given an iterator function constructs a Sequence that returns valuesthrough the Iterator provided by that function. The values areevaluated lazily, and the sequence is potentially infinite.
包裹在一个扩展函数中,它看起来像这样:
fun <T> Iterable<T>.toValuesThroughIteratorSequence(): Sequence<T> {
val iterator = this.iterator()
return Sequence { iterator }
}
快速测试:
data class Test(val id: Int)
val itemsList = List(45) { Test(it) }
val batchSize = 10
val repetitions = itemsList.size.div(batchSize) + 1
val itemsSeq = itemsList.toValuesThroughIteratorSequence()
(0 until repetitions).forEach { index ->
val batchSeq = itemsSeq.take(batchSize)
println("Batch no. $index: " + batchSeq.map { it.id.toString().padStart(2, ' ') }.joinToString(" "))
}
输出:
Batch no. 0: 0 1 2 3 4 5 6 7 8 9
Batch no. 1: 10 11 12 13 14 15 16 17 18 19
Batch no. 2: 20 21 22 23 24 25 26 27 28 29
Batch no. 3: 30 31 32 33 34 35 36 37 38 39
Batch no. 4: 40 41 42 43 44
关于Kotlin:将Sequence<T>按N项拆分成Sequence<Sequence<T>>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72950095/
我是一名优秀的程序员,十分优秀!