diff --git a/libraries/stdlib/samples/test/samples/collections/arrays.kt b/libraries/stdlib/samples/test/samples/collections/arrays.kt index bdc3864b251..8893aa82a50 100644 --- a/libraries/stdlib/samples/test/samples/collections/arrays.kt +++ b/libraries/stdlib/samples/test/samples/collections/arrays.kt @@ -23,6 +23,38 @@ import kotlin.test.* @RunWith(Enclosed::class) class Arrays { + class Usage { + + @Sample + fun arrayOrEmpty() { + val nullArray: Array? = null + assertPrints(nullArray.orEmpty().contentToString(), "[]") + + val array: Array? = 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]]") } - } } \ No newline at end of file diff --git a/libraries/stdlib/samples/test/samples/collections/collections.kt b/libraries/stdlib/samples/test/samples/collections/collections.kt index de680035426..1c6a17ccad7 100644 --- a/libraries/stdlib/samples/test/samples/collections/collections.kt +++ b/libraries/stdlib/samples/test/samples/collections/collections.kt @@ -23,7 +23,156 @@ import kotlin.test.* @RunWith(Enclosed::class) class Collections { + class Collections { + + @Sample + fun indicesOfCollection() { + val empty = emptyList() + assertTrue(empty.indices.isEmpty()) + val collection = listOf('a', 'b', 'c') + assertPrints(collection.indices, "0..2") + } + + @Sample + fun collectionIsNotEmpty() { + val empty = emptyList() + assertFalse(empty.isNotEmpty()) + + val collection = listOf('a', 'b', 'c') + assertTrue(collection.isNotEmpty()) + } + + @Sample + fun collectionOrEmpty() { + val nullCollection: Collection? = null + assertPrints(nullCollection.orEmpty(), "[]") + + val collection: Collection? = 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() + assertTrue(list.isEmpty()) + + val other = listOf() + 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() + assertTrue(list.isEmpty()) + + list.addAll(listOf(1, 2, 3)) + assertPrints(list, "[1, 2, 3]") + } + + @Sample + fun emptyArrayList() { + val list = arrayListOf() + 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(null) + assertPrints(empty, "[]") + + val singleton = listOfNotNull(42) + assertPrints(singleton, "[42]") + } + + @Sample + fun listOfNotNull() { + val empty = listOfNotNull(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().lastIndex, "-1") @@ -31,6 +180,80 @@ class Collections { assertPrints(list.lastIndex, "2") assertPrints(list[list.lastIndex], "y") } + + @Sample + fun listOrEmpty() { + val nullList: List? = null + assertPrints(nullList.orEmpty(), "[]") + + val list: List? = listOf('a', 'b', 'c') + assertPrints(list.orEmpty(), "[a, b, c]") + } + + @Sample + fun enumerationToList() { + val numbers = java.util.Hashtable() + 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 { diff --git a/libraries/stdlib/samples/test/samples/text/strings.kt b/libraries/stdlib/samples/test/samples/text/strings.kt index 075b99746b8..7534bdfe5e7 100644 --- a/libraries/stdlib/samples/test/samples/text/strings.kt +++ b/libraries/stdlib/samples/test/samples/text/strings.kt @@ -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") + } + } diff --git a/libraries/stdlib/src/kotlin/collections/Arrays.kt b/libraries/stdlib/src/kotlin/collections/Arrays.kt index c5eae3322bb..92c72fe9fe7 100644 --- a/libraries/stdlib/src/kotlin/collections/Arrays.kt +++ b/libraries/stdlib/src/kotlin/collections/Arrays.kt @@ -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 Array>.flatten(): List { val result = ArrayList(sumBy { it.size }) @@ -37,6 +38,7 @@ public fun Array>.flatten(): List { * 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 Array>.unzip(): Pair, List> { val listT = ArrayList(size) diff --git a/libraries/stdlib/src/kotlin/collections/ArraysJVM.kt b/libraries/stdlib/src/kotlin/collections/ArraysJVM.kt index 4ea9d738da8..10f67beb1a1 100644 --- a/libraries/stdlib/src/kotlin/collections/ArraysJVM.kt +++ b/libraries/stdlib/src/kotlin/collections/ArraysJVM.kt @@ -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 Array?.orEmpty(): Array = this ?: emptyArray() /** * 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 Collection.toTypedArray(): Array { diff --git a/libraries/stdlib/src/kotlin/collections/Collections.kt b/libraries/stdlib/src/kotlin/collections/Collections.kt index 470ea7499d2..0c734b739c6 100644 --- a/libraries/stdlib/src/kotlin/collections/Collections.kt +++ b/libraries/stdlib/src/kotlin/collections/Collections.kt @@ -73,50 +73,79 @@ private class ArrayAsCollection(val values: Array, val isVarargs: Bool public fun toArray(): Array = 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 emptyList(): List = 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 listOf(vararg elements: T): List = 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 listOf(): List = 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 listOf(element: T): List = 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 mutableListOf(): MutableList = 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 arrayListOf(): ArrayList = 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 mutableListOf(vararg elements: T): MutableList = 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 arrayListOf(vararg elements: T): ArrayList = 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 listOfNotNull(element: T?): List = 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 listOfNotNull(vararg elements: T?): List = 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 List(size: Int, init: (index: Int) -> T): List = 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 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 List.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 Collection.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 Collection?.orEmpty(): Collection = 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 List?.orEmpty(): List = 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 java.util.Enumeration.toList(): List = 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`. + * @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 Array.copyToArrayOfAny(isVarargs: Boolean): Array = * 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 > List.binarySearch(element: T?, fromIndex: Int = 0, toIndex: Int = size): Int { rangeCheck(size, fromIndex, toIndex) @@ -250,6 +294,7 @@ public fun > List.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 List.binarySearch(element: T, comparator: Comparator, fromIndex: Int = 0, toIndex: Int = size): Int { rangeCheck(size, fromIndex, toIndex) @@ -286,6 +331,7 @@ public fun List.binarySearch(element: T, comparator: Comparator, 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 > List.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 > List.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 List.binarySearch(fromIndex: Int = 0, toIndex: Int = size, comparison: (T) -> Int): Int { rangeCheck(size, fromIndex, toIndex) diff --git a/libraries/stdlib/src/kotlin/text/StringsJVM.kt b/libraries/stdlib/src/kotlin/text/StringsJVM.kt index 37b64a4fd6e..0352e98762d 100644 --- a/libraries/stdlib/src/kotlin/text/StringsJVM.kt +++ b/libraries/stdlib/src/kotlin/text/StringsJVM.kt @@ -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)