Provide samples for list, collection and array related functions #KT-20357

This commit is contained in:
Alexey Belkov
2017-10-18 01:57:38 +03:00
committed by Ilya Gorbunov
parent 97332aaeea
commit 72354559e5
7 changed files with 331 additions and 14 deletions
@@ -23,6 +23,38 @@ import kotlin.test.*
@RunWith(Enclosed::class)
class Arrays {
class Usage {
@Sample
fun arrayOrEmpty() {
val nullArray: Array<Any>? = null
assertPrints(nullArray.orEmpty().contentToString(), "[]")
val array: Array<Char>? = arrayOf('a', 'b', 'c')
assertPrints(array.orEmpty().contentToString(), "[a, b, c]")
}
}
class Transformations {
@Sample
fun flattenArray() {
val deepArray = arrayOf(
arrayOf(1),
arrayOf(2, 3),
arrayOf(4, 5, 6)
)
assertPrints(deepArray.flatten(), "[1, 2, 3, 4, 5, 6]")
}
@Sample
fun unzipArray() {
val array = arrayOf(1 to 'a', 2 to 'b', 3 to 'c')
assertPrints(array.unzip(), "([1, 2, 3], [a, b, c])")
}
}
class ContentOperations {
@Sample
@@ -42,7 +74,6 @@ class Arrays {
assertPrints(matrix.contentDeepToString(), "[[3, 7, 9], [0, 1, 0], [2, 4, 8]]")
}
}
}
@@ -23,7 +23,156 @@ import kotlin.test.*
@RunWith(Enclosed::class)
class Collections {
class Collections {
@Sample
fun indicesOfCollection() {
val empty = emptyList<Any>()
assertTrue(empty.indices.isEmpty())
val collection = listOf('a', 'b', 'c')
assertPrints(collection.indices, "0..2")
}
@Sample
fun collectionIsNotEmpty() {
val empty = emptyList<Any>()
assertFalse(empty.isNotEmpty())
val collection = listOf('a', 'b', 'c')
assertTrue(collection.isNotEmpty())
}
@Sample
fun collectionOrEmpty() {
val nullCollection: Collection<Any>? = null
assertPrints(nullCollection.orEmpty(), "[]")
val collection: Collection<Char>? = listOf('a', 'b', 'c')
assertPrints(collection.orEmpty(), "[a, b, c]")
}
@Sample
fun collectionContainsAll() {
val collection = mutableListOf('a', 'b')
val test = listOf('a', 'b', 'c')
assertFalse(collection.containsAll(test))
collection.add('c')
assertTrue(collection.containsAll(test))
}
@Sample
fun collectionToTypedArray() {
val collection = listOf(1, 2, 3)
val array = collection.toTypedArray()
assertPrints(array.contentToString(), "[1, 2, 3]")
}
}
class Lists {
@Sample
fun emptyReadOnlyList() {
val list = emptyList<Int>()
assertTrue(list.isEmpty())
val other = listOf<String>()
assertTrue(list == other, "Empty lists are equal")
assertPrints(list, "[]")
assertFails { list[0] }
}
@Sample
fun readOnlyList() {
val list = listOf('a', 'b', 'c')
assertPrints(list.count(), "3")
assertTrue(list.contains('a'))
assertPrints(list.indexOf('b'), "1")
assertPrints(list[2], "c")
}
@Sample
fun singletonReadOnlyList() {
val list = listOf('a')
assertPrints(list, "[a]")
assertPrints(list.count(), "1")
}
@Sample
fun emptyMutableList() {
val list = mutableListOf<Int>()
assertTrue(list.isEmpty())
list.addAll(listOf(1, 2, 3))
assertPrints(list, "[1, 2, 3]")
}
@Sample
fun emptyArrayList() {
val list = arrayListOf<Int>()
assertTrue(list.isEmpty())
list.addAll(listOf(1, 2, 3))
assertPrints(list, "[1, 2, 3]")
}
@Sample
fun mutableList() {
val list = mutableListOf(1, 2, 3)
assertPrints(list, "[1, 2, 3]")
list.addAll(listOf(4, 5))
assertPrints(list, "[1, 2, 3, 4, 5]")
}
@Sample
fun arrayList() {
val list = arrayListOf(1, 2, 3)
assertPrints(list, "[1, 2, 3]")
list.addAll(listOf(4, 5))
assertPrints(list, "[1, 2, 3, 4, 5]")
}
@Sample
fun singletonListOfNotNull() {
val empty = listOfNotNull<Any>(null)
assertPrints(empty, "[]")
val singleton = listOfNotNull(42)
assertPrints(singleton, "[42]")
}
@Sample
fun listOfNotNull() {
val empty = listOfNotNull<Any>(null)
assertPrints(empty, "[]")
val list = listOfNotNull(1, null, 2, null, 3)
assertPrints(list, "[1, 2, 3]")
}
@Sample
fun readOnlyListFromInitializer() {
val empty = List(0) {}
assertPrints(empty, "[]")
val squares = List(5) { (it + 1) * (it + 1) }
assertPrints(squares, "[1, 4, 9, 16, 25]")
}
@Sample
fun mutableListFromInitializer() {
val chars = listOf('a', 'b', 'c', 'd')
val list = MutableList(3) { chars[it] }
assertPrints(list, "[a, b, c]")
list.add(chars[3])
assertTrue(list == chars)
}
@Sample
fun lastIndexOfList() {
assertPrints(emptyList<Any>().lastIndex, "-1")
@@ -31,6 +180,80 @@ class Collections {
assertPrints(list.lastIndex, "2")
assertPrints(list[list.lastIndex], "y")
}
@Sample
fun listOrEmpty() {
val nullList: List<Any>? = null
assertPrints(nullList.orEmpty(), "[]")
val list: List<Char>? = listOf('a', 'b', 'c')
assertPrints(list.orEmpty(), "[a, b, c]")
}
@Sample
fun enumerationToList() {
val numbers = java.util.Hashtable<String, Int>()
numbers.put("one", 1)
numbers.put("two", 2)
numbers.put("three", 3)
val enumeration = numbers.elements()
val list = enumeration.toList().sorted()
assertPrints(list, "[1, 2, 3]")
}
@Sample
fun binarySearchOnComparable() {
val list = mutableListOf('a', 'b', 'c', 'd', 'e')
assertPrints(list.binarySearch('d'), "3")
list.remove('d')
val invertedInsertionPoint = list.binarySearch('d')
val actualInsertionPoint = -(invertedInsertionPoint + 1)
assertPrints(actualInsertionPoint, "3")
list.add(actualInsertionPoint, 'd')
assertPrints(list, "[a, b, c, d, e]")
}
@Sample
fun binarySearchWithBoundaries() {
val list = listOf('a', 'b', 'c', 'd', 'e')
assertPrints(list.binarySearch('d'), "3")
// element is out of range from the left
assertTrue(list.binarySearch('b', fromIndex = 2) < 0)
// element is out of range from the right
assertTrue(list.binarySearch('d', toIndex = 2) < 0)
}
@Sample
fun binarySearchWithComparator() {
val colors = listOf("Blue", "green", "ORANGE", "Red", "yellow")
assertPrints(colors.binarySearch("RED", String.CASE_INSENSITIVE_ORDER), "3")
}
@Sample
fun binarySearchByKey() {
data class Box(val value: Int)
val numbers = listOf(1, 3, 7, 10, 12)
val boxes = numbers.map { Box(it) }
assertPrints(boxes.binarySearchBy(10) { it.value }, "3")
}
@Sample
fun binarySearchWithComparisonFunction() {
data class Box(val value: Int)
val numbers = listOf(12, 10, 7, 3, 1)
val boxes = numbers.map { Box(it) }
// `boxes` is sorted according to the comparison function
assertPrints(boxes.binarySearch { 10 - it.value }, "1")
}
}
class Transformations {
@@ -71,4 +71,12 @@ class Strings {
assertPrints(proteins.take(5).toList(), "[Isoleucine, Arginine, Glycine, Arginine, Glutamine]")
}
@Sample
fun stringToByteArray() {
val charset = Charsets.UTF_8
val byteArray = "Hello".toByteArray(charset)
assertPrints(byteArray.contentToString(), "[72, 101, 108, 108, 111]")
assertPrints(byteArray.toString(charset), "Hello")
}
}
@@ -24,6 +24,7 @@ package kotlin.collections
/**
* Returns a single list of all elements from all arrays in the given array.
* @sample samples.collections.Arrays.Transformations.flattenArray
*/
public fun <T> Array<out Array<out T>>.flatten(): List<T> {
val result = ArrayList<T>(sumBy { it.size })
@@ -37,6 +38,7 @@ public fun <T> Array<out Array<out T>>.flatten(): List<T> {
* Returns a pair of lists, where
* *first* list is built from the first values of each pair from this array,
* *second* list is built from the second values of each pair from this array.
* @sample samples.collections.Arrays.Transformations.unzipArray
*/
public fun <T, R> Array<out Pair<T, R>>.unzip(): Pair<List<T>, List<R>> {
val listT = ArrayList<T>(size)
@@ -23,11 +23,15 @@ package kotlin.collections
import java.nio.charset.Charset
/** Returns the array if it's not `null`, or an empty array otherwise. */
/**
* Returns the array if it's not `null`, or an empty array otherwise.
* @sample samples.collections.Arrays.Usage.arrayOrEmpty
*/
public inline fun <reified T> Array<out T>?.orEmpty(): Array<out T> = this ?: emptyArray<T>()
/**
* Converts the contents of this byte array to a string using the specified [charset].
* @sample samples.text.Strings.stringToByteArray
*/
@kotlin.internal.InlineOnly
public inline fun ByteArray.toString(charset: Charset): String = String(this, charset)
@@ -37,6 +41,7 @@ public inline fun ByteArray.toString(charset: Charset): String = String(this, ch
*
* Allocates an array of runtime type `T` having its size equal to the size of this collection
* and populates the array with the elements of this collection.
* @sample samples.collections.Collections.Collections.collectionToTypedArray
*/
@Suppress("UNCHECKED_CAST")
public inline fun <reified T> Collection<T>.toTypedArray(): Array<T> {
@@ -73,50 +73,79 @@ private class ArrayAsCollection<T>(val values: Array<out T>, val isVarargs: Bool
public fun toArray(): Array<out Any?> = values.copyToArrayOfAny(isVarargs)
}
/** Returns an empty read-only list. The returned list is serializable (JVM). */
/**
* Returns an empty read-only list. The returned list is serializable (JVM).
* @sample samples.collections.Collections.Lists.emptyReadOnlyList
*/
public fun <T> emptyList(): List<T> = EmptyList
/** Returns a new read-only list of given elements. The returned list is serializable (JVM). */
/**
* Returns a new read-only list of given elements. The returned list is serializable (JVM).
* @sample samples.collections.Collections.Lists.readOnlyList
*/
public fun <T> listOf(vararg elements: T): List<T> = if (elements.size > 0) elements.asList() else emptyList()
/** Returns an empty read-only list. The returned list is serializable (JVM). */
/**
* Returns an empty read-only list. The returned list is serializable (JVM).
* @sample samples.collections.Collections.Lists.emptyReadOnlyList
*/
@kotlin.internal.InlineOnly
public inline fun <T> listOf(): List<T> = emptyList()
/**
* Returns an immutable list containing only the specified object [element].
* The returned list is serializable.
* @sample samples.collections.Collections.Lists.singletonReadOnlyList
*/
@JvmVersion
public fun <T> listOf(element: T): List<T> = java.util.Collections.singletonList(element)
/** Returns an empty new [MutableList]. */
/**
* Returns an empty new [MutableList].
* @sample samples.collections.Collections.Lists.emptyMutableList
*/
@SinceKotlin("1.1")
@kotlin.internal.InlineOnly
public inline fun <T> mutableListOf(): MutableList<T> = ArrayList()
/** Returns an empty new [ArrayList]. */
/**
* Returns an empty new [ArrayList].
* @sample samples.collections.Collections.Lists.emptyArrayList
*/
@SinceKotlin("1.1")
@kotlin.internal.InlineOnly
public inline fun <T> arrayListOf(): ArrayList<T> = ArrayList()
/** Returns a new [MutableList] with the given elements. */
/**
* Returns a new [MutableList] with the given elements.
* @sample samples.collections.Collections.Lists.mutableList
*/
public fun <T> mutableListOf(vararg elements: T): MutableList<T>
= if (elements.size == 0) ArrayList() else ArrayList(ArrayAsCollection(elements, isVarargs = true))
/** Returns a new [ArrayList] with the given elements. */
/**
* Returns a new [ArrayList] with the given elements.
* @sample samples.collections.Collections.Lists.arrayList
*/
public fun <T> arrayListOf(vararg elements: T): ArrayList<T>
= if (elements.size == 0) ArrayList() else ArrayList(ArrayAsCollection(elements, isVarargs = true))
/** Returns a new read-only list either of single given element, if it is not null, or empty list it the element is null. The returned list is serializable (JVM). */
/**
* Returns a new read-only list either of single given element, if it is not null, or empty list if the element is null. The returned list is serializable (JVM).
* @sample samples.collections.Collections.Lists.singletonListOfNotNull
*/
public fun <T : Any> listOfNotNull(element: T?): List<T> = if (element != null) listOf(element) else emptyList()
/** Returns a new read-only list only of those given elements, that are not null. The returned list is serializable (JVM). */
/**
* Returns a new read-only list only of those given elements, that are not null. The returned list is serializable (JVM).
* @sample samples.collections.Collections.Lists.listOfNotNull
*/
public fun <T : Any> listOfNotNull(vararg elements: T?): List<T> = elements.filterNotNull()
/**
* Creates a new read-only list with the specified [size], where each element is calculated by calling the specified
* [init] function. The [init] function returns a list element given its index.
* @sample samples.collections.Collections.Lists.readOnlyListFromInitializer
*/
@SinceKotlin("1.1")
@kotlin.internal.InlineOnly
@@ -125,6 +154,7 @@ public inline fun <T> List(size: Int, init: (index: Int) -> T): List<T> = Mutabl
/**
* Creates a new mutable list with the specified [size], where each element is calculated by calling the specified
* [init] function. The [init] function returns a list element given its index.
* @sample samples.collections.Collections.Lists.mutableListFromInitializer
*/
@SinceKotlin("1.1")
@kotlin.internal.InlineOnly
@@ -136,6 +166,7 @@ public inline fun <T> MutableList(size: Int, init: (index: Int) -> T): MutableLi
/**
* Returns an [IntRange] of the valid indices for this collection.
* @sample samples.collections.Collections.Collections.indicesOfCollection
*/
public val Collection<*>.indices: IntRange
get() = 0..size - 1
@@ -148,21 +179,31 @@ public val Collection<*>.indices: IntRange
public val <T> List<T>.lastIndex: Int
get() = this.size - 1
/** Returns `true` if the collection is not empty. */
/**
* Returns `true` if the collection is not empty.
* @sample samples.collections.Collections.Collections.collectionIsNotEmpty
*/
@kotlin.internal.InlineOnly
public inline fun <T> Collection<T>.isNotEmpty(): Boolean = !isEmpty()
/** Returns this Collection if it's not `null` and the empty list otherwise. */
/**
* Returns this Collection if it's not `null` and the empty list otherwise.
* @sample samples.collections.Collections.Collections.collectionOrEmpty
*/
@kotlin.internal.InlineOnly
public inline fun <T> Collection<T>?.orEmpty(): Collection<T> = this ?: emptyList()
/** Returns this List if it's not `null` and the empty list otherwise. */
/**
* Returns this List if it's not `null` and the empty list otherwise.
* @sample samples.collections.Collections.Lists.listOrEmpty
*/
@kotlin.internal.InlineOnly
public inline fun <T> List<T>?.orEmpty(): List<T> = this ?: emptyList()
/**
* Returns a list containing the elements returned by this enumeration
* in the order they are returned by the enumeration.
* @sample samples.collections.Collections.Lists.enumerationToList
*/
@JvmVersion
@kotlin.internal.InlineOnly
@@ -172,6 +213,7 @@ public inline fun <T> java.util.Enumeration<T>.toList(): List<T> = java.util.Col
* Checks if all elements in the specified collection are contained in this collection.
*
* Allows to overcome type-safety restriction of `containsAll` that requires to pass a collection of type `Collection<E>`.
* @sample samples.collections.Collections.Collections.collectionContainsAll
*/
@Suppress("EXTENSION_SHADOWED_BY_MEMBER") // false warning, extension takes precedence in some cases
@kotlin.internal.InlineOnly
@@ -215,6 +257,8 @@ private fun <T> Array<out T>.copyToArrayOfAny(isVarargs: Boolean): Array<Any?> =
* otherwise, the inverted insertion point `(-insertion point - 1)`.
* The insertion point is defined as the index at which the element should be inserted,
* so that the list (or the specified subrange of list) still remains sorted.
* @sample samples.collections.Collections.Lists.binarySearchOnComparable
* @sample samples.collections.Collections.Lists.binarySearchWithBoundaries
*/
public fun <T: Comparable<T>> List<T?>.binarySearch(element: T?, fromIndex: Int = 0, toIndex: Int = size): Int {
rangeCheck(size, fromIndex, toIndex)
@@ -250,6 +294,7 @@ public fun <T: Comparable<T>> List<T?>.binarySearch(element: T?, fromIndex: Int
* otherwise, the inverted insertion point `(-insertion point - 1)`.
* The insertion point is defined as the index at which the element should be inserted,
* so that the list (or the specified subrange of list) still remains sorted according to the specified [comparator].
* @sample samples.collections.Collections.Lists.binarySearchWithComparator
*/
public fun <T> List<T>.binarySearch(element: T, comparator: Comparator<in T>, fromIndex: Int = 0, toIndex: Int = size): Int {
rangeCheck(size, fromIndex, toIndex)
@@ -286,6 +331,7 @@ public fun <T> List<T>.binarySearch(element: T, comparator: Comparator<in T>, fr
* otherwise, the inverted insertion point `(-insertion point - 1)`.
* The insertion point is defined as the index at which the element should be inserted,
* so that the list (or the specified subrange of list) still remains sorted.
* @sample samples.collections.Collections.Lists.binarySearchByKey
*/
public inline fun <T, K : Comparable<K>> List<T>.binarySearchBy(key: K?, fromIndex: Int = 0, toIndex: Int = size, crossinline selector: (T) -> K?): Int =
binarySearch(fromIndex, toIndex) { compareValues(selector(it), key) }
@@ -308,6 +354,7 @@ public inline fun <T, K : Comparable<K>> List<T>.binarySearchBy(key: K?, fromInd
* otherwise, the inverted insertion point `(-insertion point - 1)`.
* The insertion point is defined as the index at which the element should be inserted,
* so that the list (or the specified subrange of list) still remains sorted.
* @sample samples.collections.Collections.Lists.binarySearchWithComparisonFunction
*/
public fun <T> List<T>.binarySearch(fromIndex: Int = 0, toIndex: Int = size, comparison: (T) -> Int): Int {
rangeCheck(size, fromIndex, toIndex)
@@ -367,6 +367,7 @@ public inline fun String.toUpperCase(locale: java.util.Locale): String = (this a
/**
* Encodes the contents of this string using the specified character set and returns the resulting byte array.
* @sample samples.text.Strings.stringToByteArray
*/
@kotlin.internal.InlineOnly
public inline fun String.toByteArray(charset: Charset = Charsets.UTF_8): ByteArray = (this as java.lang.String).getBytes(charset)