stdlib: Provide Collection.toArray() implementation
It also modifies the test for this method to make it to not rely on Kotlin JVM implementation.
This commit is contained in:
Vendored
+19
-17
@@ -3,28 +3,30 @@ import kotlin.comparisons.*
|
||||
|
||||
fun box() {
|
||||
class TestCollection<out E>(val data: Collection<E>) : AbstractCollection<E>() {
|
||||
val invocations = mutableListOf<String>()
|
||||
override val size get() = data.size
|
||||
override fun iterator() = data.iterator()
|
||||
|
||||
override fun toArray(): Array<Any?> {
|
||||
invocations += "toArray1"
|
||||
return data.toTypedArray()
|
||||
}
|
||||
|
||||
public override fun <T> toArray(array: Array<T>): Array<T> {
|
||||
invocations += "toArray2"
|
||||
return super.toArray(array)
|
||||
}
|
||||
public override fun toArray(): Array<Any?> = super.toArray()
|
||||
public override fun <T> toArray(array: Array<T>): Array<T> = super.toArray(array)
|
||||
}
|
||||
|
||||
val data = listOf("abc", "def")
|
||||
val coll = TestCollection(data)
|
||||
val data = listOf(1, 2, 3)
|
||||
assertEquals(TestCollection(data).toArray().asList(), data)
|
||||
assertEquals(TestCollection(listOf<Int>()).toArray().size, 0)
|
||||
|
||||
val arr1 = coll.toTypedArray()
|
||||
assertEquals(data, arr1.asList())
|
||||
assertTrue("toArray1" in coll.invocations || "toArray2" in coll.invocations)
|
||||
var arr1 = Array<Int>(3) { -1 }
|
||||
var arr2 = TestCollection(data).toArray(arr1)
|
||||
assertTrue(arr1 === arr2)
|
||||
assertEquals(arr2.asList(), data)
|
||||
|
||||
arr1 = Array<Int>(4) { -1 }
|
||||
arr2 = TestCollection(data).toArray(arr1)
|
||||
assertTrue(arr1 === arr2)
|
||||
assertEquals(arr2.asList(), data + listOf(-1))
|
||||
|
||||
arr1 = Array<Int>(2) { -1 }
|
||||
arr2 = TestCollection(data).toArray(arr1)
|
||||
assertFalse(arr1 === arr2)
|
||||
assertEquals(arr2.asList(), data)
|
||||
|
||||
val arr2: Array<String> = coll.toArray(Array(coll.size + 1) { "" })
|
||||
assertEquals(data + listOf(null), arr2.asList())
|
||||
}
|
||||
|
||||
@@ -16,6 +16,12 @@
|
||||
|
||||
package kotlin.collections
|
||||
|
||||
/**
|
||||
* Provides a skeletal implementation of the read-only [Collection] interface.
|
||||
*
|
||||
* @param E the type of elements contained in the collection. The collection is covariant on its element type.
|
||||
*/
|
||||
@SinceKotlin("1.1")
|
||||
public abstract class AbstractCollection<out E> protected constructor() : Collection<E> {
|
||||
abstract override val size: Int
|
||||
abstract override fun iterator(): Iterator<E>
|
||||
@@ -31,4 +37,15 @@ public abstract class AbstractCollection<out E> protected constructor() : Collec
|
||||
override fun toString(): String = joinToString(", ", "[", "]") {
|
||||
if (it === this) "(this Collection)" else it.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns new array of type `Array<Any?>` with the elements of this collection.
|
||||
*/
|
||||
protected open fun toArray(): Array<Any?> = collectionToArray(this)
|
||||
|
||||
/**
|
||||
* Fills the provided [array] or creates new array of the same type
|
||||
* and fills it with the elements of this collection.
|
||||
*/
|
||||
protected open fun <T> toArray(array: Array<T>): Array<T> = collectionToArray(this, array)
|
||||
}
|
||||
|
||||
@@ -55,6 +55,33 @@ fun <E> Array<E>.copyOfNulls(fromIndex: Int, toIndex: Int): Array<E?> {
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies elements of the [collection] into the given [array].
|
||||
* If the array is too small, allocates a new one of collection.size size.
|
||||
* @return [array] with the elements copied from the collection.
|
||||
*/
|
||||
internal fun <E, T> collectionToArray(collection: Collection<E>, array: Array<T>): Array<T> {
|
||||
val toArray = if (collection.size > array.size) {
|
||||
arrayOfUninitializedElements<T>(collection.size)
|
||||
} else {
|
||||
array
|
||||
}
|
||||
var i = 0
|
||||
// TODO: What about a concurrent modification of the collection? Do we need to handle it here?
|
||||
for (v in collection) {
|
||||
toArray[i] = v as T
|
||||
i++
|
||||
}
|
||||
return toArray
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of collection.size size and copies elements of the [collection] into it.
|
||||
* @return [array] with the elements copied from the collection.
|
||||
*/
|
||||
internal fun <E> collectionToArray(collection: Collection<E>): Array<E>
|
||||
= collectionToArray(collection, arrayOfUninitializedElements(collection.size))
|
||||
|
||||
/**
|
||||
* Returns new array which is a copy of the original array's range between [fromIndex] (inclusive)
|
||||
* and [toIndex] (exclusive) with new elements filled with **lateinit** _uninitialized_ values.
|
||||
|
||||
Reference in New Issue
Block a user