如何在 Kotlin 中高效地将 Sequence
转换为 Array
(或原始数组,例如 IntArray
)?
我发现 Sequence
没有 toArray()
方法。而 toList().toArray()
(toList().toIntArray()
)会创建额外的临时列表。
如何在 Kotlin 中高效地将 Sequence
转换为 Array
(或原始数组,例如 IntArray
)?
我发现 Sequence
没有 toArray()
方法。而 toList().toArray()
(toList().toIntArray()
)会创建额外的临时列表。
没有toArray()
方法,因为与列表不同,序列不允许查找其包含的元素数量(实际上可以是无限的),因此不可能分配正确大小的数组。
如果您在特定情况下了解序列的某些信息,则可以通过手动从序列复制元素到数组并分配数组来编写更高效的实现。例如,如果已知大小,则可以使用以下函数:
fun Sequence<Int>.toIntArray(size: Int): IntArray {
val iter = iterator()
return IntArray(size) { iter.next() }
}
toArray(size: Int)
(toIntArray(size: Int)
),用于“分配一个数组并将序列中的元素复制到数组中”? - Shreck YeSequence<T>
确实有toList()
方法,但它也需要知道元素的数量,因此第一段的推理是值得怀疑的。看起来他们本可以在旁边添加toArray()
方法。 - HakanaiList
接口的实现不需要您事先知道元素数量。特别是,ArrayList
从一个容量开始,但随着需要而增长。LinkedList
根本不关心。数组无法在没有大小的情况下构建。假设的toArray
可以创建任意大小的数组,然后在迭代序列时按需分配新的(更大的)数组,但那将重新实现ArrayList
- 我看不出有什么意义。但是,对于某些人来说,toArray(size: Int)
可能会很有用。 - JoffreyArrayList
来实现它。甚至可以将其实现为 toList().toXArray()
。重点是,Kotlin的Sequence<T>
没有将序列转换为数组的方法,而Java的Stream<T>
则有。这是Kotlin API中的一个空缺,预计在某个时间点会被填补,但现在它是一个明显的疏漏。 - HakanaitoArray()
方法的人会期望它 不 经过列表,否则他们可能会直接使用列表。数组在一般情况下使用起来不太方便,在 Kotlin 中也不太常见,除非你有特定的性能需求,即使在这种情况下,使用 ArrayList
实现的 toArray
也会非常糟糕。因此,我认为添加这样的 API 没有太多好处(特别是因为它会让用户误以为它会直接收集到一个数组中)。 - Joffrey我希望为Sequence<T>
添加一个版本。使用refied T(需要函数是内联的)来创建正确类型的数组,在Java中不可能实现:D
inline fun <reified T> Sequence<T>.toArray(size: Int): Array<T> {
val iter = iterator()
return Array(size) { iter.next() }
}
Array<T>
会创建一个低效的对象数组而不是原始数组。 - Shreck Ye因为我不能写评论,这是原始类型最高答案的另一个版本。
fun <I, O> Sequence<I>.toArray(
size: Int,
factory: (size: Int, init: (Int) -> I) -> O
): O {
val iter = iterator()
return factory(size) { iter.next() }
}
//usage
seq<Byte>
.toArray(size, ::ByteArray)