Add samples for Comparisons #KT-20357
This commit is contained in:
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package samples.comparisons
|
||||
|
||||
import samples.*
|
||||
import kotlin.test.*
|
||||
|
||||
class Comparisons {
|
||||
@Sample
|
||||
fun compareValuesByWithSingleSelector() {
|
||||
fun compareLength(a: String, b: String): Int =
|
||||
compareValuesBy(a, b) { it.length }
|
||||
|
||||
assertTrue(compareLength("a", "b") == 0)
|
||||
assertTrue(compareLength("bb", "a") > 0)
|
||||
assertTrue(compareLength("a", "bb") < 0)
|
||||
}
|
||||
|
||||
@Sample
|
||||
fun compareValuesByWithSelectors() {
|
||||
fun compareLengthThenString(a: String, b: String): Int =
|
||||
compareValuesBy(a, b, { it.length }, { it })
|
||||
|
||||
assertTrue(compareLengthThenString("b", "aa") < 0)
|
||||
|
||||
assertTrue(compareLengthThenString("a", "b") < 0)
|
||||
assertTrue(compareLengthThenString("b", "a") > 0)
|
||||
assertTrue(compareLengthThenString("a", "a") == 0)
|
||||
}
|
||||
|
||||
@Sample
|
||||
fun compareValuesByWithComparator() {
|
||||
fun compareInsensitiveOrder(a: Char, b: Char): Int =
|
||||
compareValuesBy(a, b, String.CASE_INSENSITIVE_ORDER, { c -> c.toString() })
|
||||
|
||||
assertTrue(compareInsensitiveOrder('a', 'a') == 0)
|
||||
assertTrue(compareInsensitiveOrder('a', 'A') == 0)
|
||||
|
||||
assertTrue(compareInsensitiveOrder('a', 'b') < 0)
|
||||
assertTrue(compareInsensitiveOrder('A', 'b') < 0)
|
||||
assertTrue(compareInsensitiveOrder('b', 'a') > 0)
|
||||
}
|
||||
|
||||
@Sample
|
||||
fun compareValues() {
|
||||
assertTrue(compareValues(null, 1) < 0)
|
||||
assertTrue(compareValues(1, 2) < 0)
|
||||
assertTrue(compareValues(2, 1) > 0)
|
||||
assertTrue(compareValues(1, 1) == 0)
|
||||
}
|
||||
|
||||
@Sample
|
||||
fun compareByWithSingleSelector() {
|
||||
val list = listOf("aa", "b", "bb", "a")
|
||||
|
||||
val sorted = list.sortedWith(compareBy { it.length })
|
||||
|
||||
assertPrints(sorted, "[b, a, aa, bb]")
|
||||
}
|
||||
|
||||
@Sample
|
||||
fun compareByWithSelectors() {
|
||||
val list = listOf("aa", "b", "bb", "a")
|
||||
|
||||
val sorted = list.sortedWith(compareBy(
|
||||
{ it.length },
|
||||
{ it }
|
||||
))
|
||||
|
||||
assertPrints(sorted, "[a, b, aa, bb]")
|
||||
}
|
||||
|
||||
@Sample
|
||||
fun compareByWithComparator() {
|
||||
val list = listOf('B', 'a', 'A', 'b')
|
||||
|
||||
val sorted = list.sortedWith(
|
||||
compareBy(String.CASE_INSENSITIVE_ORDER) { v -> v.toString() }
|
||||
)
|
||||
|
||||
assertPrints(sorted, "[a, A, B, b]")
|
||||
}
|
||||
|
||||
@Sample
|
||||
fun compareByDescendingWithSingleSelector() {
|
||||
val list = listOf("aa", "b", "bb", "a")
|
||||
|
||||
val sorted = list.sortedWith(compareByDescending { it.length })
|
||||
|
||||
assertPrints(sorted, "[aa, bb, b, a]")
|
||||
}
|
||||
|
||||
@Sample
|
||||
fun compareByDescendingWithComparator() {
|
||||
val list = listOf('B', 'a', 'A', 'b')
|
||||
|
||||
val sorted = list.sortedWith(
|
||||
compareByDescending(String.CASE_INSENSITIVE_ORDER) { v -> v.toString() }
|
||||
)
|
||||
|
||||
assertPrints(sorted, "[B, b, a, A]")
|
||||
}
|
||||
|
||||
@Sample
|
||||
fun thenBy() {
|
||||
val list = listOf("aa", "b", "bb", "a")
|
||||
|
||||
val lengthComparator = compareBy<String> { it.length }
|
||||
assertPrints(list.sortedWith(lengthComparator), "[b, a, aa, bb]")
|
||||
|
||||
val lengthThenString = lengthComparator.thenBy { it }
|
||||
assertPrints(list.sortedWith(lengthThenString), "[a, b, aa, bb]")
|
||||
}
|
||||
|
||||
@Sample
|
||||
fun thenByWithComparator() {
|
||||
val list = listOf("A", "aa", "b", "bb", "a")
|
||||
|
||||
val lengthComparator = compareBy<String> { it.length }
|
||||
assertPrints(list.sortedWith(lengthComparator), "[A, b, a, aa, bb]")
|
||||
|
||||
val lengthThenCaseInsensitive = lengthComparator
|
||||
.thenBy(String.CASE_INSENSITIVE_ORDER) { it }
|
||||
assertPrints(list.sortedWith(lengthThenCaseInsensitive), "[A, a, b, aa, bb]")
|
||||
}
|
||||
|
||||
@Sample
|
||||
fun thenByDescending() {
|
||||
val list = listOf("aa", "b", "bb", "a")
|
||||
|
||||
val lengthComparator = compareBy<String> { it.length }
|
||||
assertPrints(list.sortedWith(lengthComparator), "[b, a, aa, bb]")
|
||||
|
||||
val lengthThenStringDesc = lengthComparator.thenByDescending { it }
|
||||
assertPrints(list.sortedWith(lengthThenStringDesc), "[b, a, bb, aa]")
|
||||
}
|
||||
|
||||
@Sample
|
||||
fun thenByDescendingWithComparator() {
|
||||
val list = listOf("A", "aa", "b", "bb", "a")
|
||||
|
||||
val lengthComparator = compareBy<String> { it.length }
|
||||
assertPrints(list.sortedWith(lengthComparator), "[A, b, a, aa, bb]")
|
||||
|
||||
val lengthThenCaseInsensitive = lengthComparator
|
||||
.thenByDescending(String.CASE_INSENSITIVE_ORDER) { it }
|
||||
assertPrints(list.sortedWith(lengthThenCaseInsensitive), "[b, A, a, bb, aa]")
|
||||
}
|
||||
|
||||
@Sample
|
||||
fun thenComparator() {
|
||||
val array = arrayOf("c" to 1, "b" to 2, "a" to 1, "d" to 0, null to 0)
|
||||
|
||||
val valueComparator = compareBy<Pair<String?, Int>> { it.second }
|
||||
val map1 = listOf(*array).sortedWith(valueComparator).toMap()
|
||||
assertPrints(map1, "{d=0, null=0, c=1, a=1, b=2}")
|
||||
|
||||
val valueThenKeyComparator = valueComparator
|
||||
.thenComparator({ a, b -> compareValues(a.first, b.first) })
|
||||
val map2 = listOf(*array).sortedWith(valueThenKeyComparator).toMap()
|
||||
assertPrints(map2, "{null=0, d=0, a=1, c=1, b=2}")
|
||||
}
|
||||
|
||||
@Sample
|
||||
fun then() {
|
||||
val list = listOf("A", "aa", "b", "bb", "a")
|
||||
|
||||
val lengthThenCaseInsensitive = compareBy<String> { it.length }
|
||||
.then(String.CASE_INSENSITIVE_ORDER)
|
||||
|
||||
val sorted = list.sortedWith(lengthThenCaseInsensitive)
|
||||
|
||||
assertPrints(sorted, "[A, a, b, aa, bb]")
|
||||
}
|
||||
|
||||
@Sample
|
||||
fun thenDescending() {
|
||||
val list = listOf("A", "aa", "b", "bb", "a")
|
||||
|
||||
val lengthThenCaseInsensitive = compareBy<String> { it.length }
|
||||
.thenDescending(String.CASE_INSENSITIVE_ORDER)
|
||||
|
||||
val sorted = list.sortedWith(lengthThenCaseInsensitive)
|
||||
|
||||
assertPrints(sorted, "[b, A, a, bb, aa]")
|
||||
}
|
||||
|
||||
@Sample
|
||||
fun nullsFirstLastComparator() {
|
||||
val list = listOf(4, null, -1, 1)
|
||||
|
||||
val nullsFirstList = list.sortedWith(nullsFirst())
|
||||
assertPrints(nullsFirstList, "[null, -1, 1, 4]")
|
||||
|
||||
val nullsLastList = list.sortedWith(nullsLast())
|
||||
assertPrints(nullsLastList, "[-1, 1, 4, null]")
|
||||
}
|
||||
|
||||
@Sample
|
||||
fun nullsFirstLastWithComparator() {
|
||||
val list = listOf(4, null, 1, -2, 3)
|
||||
|
||||
val nullsFirstList = list.sortedWith(nullsFirst(reverseOrder()))
|
||||
assertPrints(nullsFirstList, "[null, 4, 3, 1, -2]")
|
||||
|
||||
val nullsLastList = list.sortedWith(nullsLast(reverseOrder()))
|
||||
assertPrints(nullsLastList, "[4, 3, 1, -2, null]")
|
||||
}
|
||||
|
||||
@Sample
|
||||
fun naturalOrderComparator() {
|
||||
val list = listOf("aa", "b", "bb", "a")
|
||||
|
||||
val lengthThenNatural = compareBy<String> { it.length }
|
||||
.then(naturalOrder())
|
||||
|
||||
val sorted = list.sortedWith(lengthThenNatural)
|
||||
|
||||
assertPrints(sorted, "[a, b, aa, bb]")
|
||||
}
|
||||
|
||||
@Sample
|
||||
fun reversed() {
|
||||
val list = listOf("aa", "b", "bb", "a")
|
||||
|
||||
val lengthThenString = compareBy<String> { it.length }.thenBy { it }
|
||||
|
||||
val sorted = list.sortedWith(lengthThenString)
|
||||
assertPrints(sorted, "[a, b, aa, bb]")
|
||||
|
||||
val sortedReversed = list.sortedWith(lengthThenString.reversed())
|
||||
assertPrints(sortedReversed, "[bb, aa, b, a]")
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,8 @@ package kotlin.comparisons
|
||||
* The functions are called sequentially, receive the given values [a] and [b] and return [Comparable]
|
||||
* objects. As soon as the [Comparable] instances returned by a function for [a] and [b] values do not
|
||||
* compare as equal, the result of that comparison is returned.
|
||||
*
|
||||
* @sample samples.comparisons.Comparisons.compareValuesByWithSelectors
|
||||
*/
|
||||
public fun <T> compareValuesBy(a: T, b: T, vararg selectors: (T) -> Comparable<*>?): Int {
|
||||
require(selectors.size > 0)
|
||||
@@ -43,6 +45,8 @@ private fun <T> compareValuesByImpl(a: T, b: T, selectors: Array<out (T)->Compar
|
||||
* Compares two values using the specified [selector] function to calculate the result of the comparison.
|
||||
* The function is applied to the given values [a] and [b] and return [Comparable] objects.
|
||||
* The result of comparison of these [Comparable] instances is returned.
|
||||
*
|
||||
* @sample samples.comparisons.Comparisons.compareValuesByWithSingleSelector
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T> compareValuesBy(a: T, b: T, selector: (T) -> Comparable<*>?): Int {
|
||||
@@ -53,6 +57,8 @@ public inline fun <T> compareValuesBy(a: T, b: T, selector: (T) -> Comparable<*>
|
||||
* Compares two values using the specified [selector] function to calculate the result of the comparison.
|
||||
* The function is applied to the given values [a] and [b] and return objects of type K which are then being
|
||||
* compared with the given [comparator].
|
||||
*
|
||||
* @sample samples.comparisons.Comparisons.compareValuesByWithComparator
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T, K> compareValuesBy(a: T, b: T, comparator: Comparator<in K>, selector: (T) -> K): Int {
|
||||
@@ -71,6 +77,8 @@ public inline fun <T, K> compareValuesBy(a: T, b: T, comparator: Comparator<in K
|
||||
|
||||
/**
|
||||
* Compares two nullable [Comparable] values. Null is considered less than any value.
|
||||
*
|
||||
* @sample samples.comparisons.Comparisons.compareValues
|
||||
*/
|
||||
public fun <T : Comparable<*>> compareValues(a: T?, b: T?): Int {
|
||||
if (a === b) return 0
|
||||
@@ -86,6 +94,8 @@ public fun <T : Comparable<*>> compareValues(a: T?, b: T?): Int {
|
||||
* The functions are called sequentially, receive the given values `a` and `b` and return [Comparable]
|
||||
* objects. As soon as the [Comparable] instances returned by a function for `a` and `b` values do not
|
||||
* compare as equal, the result of that comparison is returned from the [Comparator].
|
||||
*
|
||||
* @sample samples.comparisons.Comparisons.compareByWithSelectors
|
||||
*/
|
||||
public fun <T> compareBy(vararg selectors: (T) -> Comparable<*>?): Comparator<T> {
|
||||
require(selectors.size > 0)
|
||||
@@ -96,6 +106,8 @@ public fun <T> compareBy(vararg selectors: (T) -> Comparable<*>?): Comparator<T>
|
||||
|
||||
/**
|
||||
* Creates a comparator using the function to transform value to a [Comparable] instance for comparison.
|
||||
*
|
||||
* @sample samples.comparisons.Comparisons.compareByWithSingleSelector
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T> compareBy(crossinline selector: (T) -> Comparable<*>?): Comparator<T> =
|
||||
@@ -104,6 +116,8 @@ public inline fun <T> compareBy(crossinline selector: (T) -> Comparable<*>?): Co
|
||||
/**
|
||||
* Creates a comparator using the [selector] function to transform values being compared and then applying
|
||||
* the specified [comparator] to compare transformed values.
|
||||
*
|
||||
* @sample samples.comparisons.Comparisons.compareByWithComparator
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T, K> compareBy(comparator: Comparator<in K>, crossinline selector: (T) -> K): Comparator<T> =
|
||||
@@ -111,6 +125,8 @@ public inline fun <T, K> compareBy(comparator: Comparator<in K>, crossinline sel
|
||||
|
||||
/**
|
||||
* Creates a descending comparator using the function to transform value to a [Comparable] instance for comparison.
|
||||
*
|
||||
* @sample samples.comparisons.Comparisons.compareByDescendingWithSingleSelector
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T> compareByDescending(crossinline selector: (T) -> Comparable<*>?): Comparator<T> =
|
||||
@@ -121,6 +137,8 @@ public inline fun <T> compareByDescending(crossinline selector: (T) -> Comparabl
|
||||
* the specified [comparator] to compare transformed values.
|
||||
*
|
||||
* Note that an order of [comparator] is reversed by this wrapper.
|
||||
*
|
||||
* @sample samples.comparisons.Comparisons.compareByDescendingWithComparator
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T, K> compareByDescending(comparator: Comparator<in K>, crossinline selector: (T) -> K): Comparator<T> =
|
||||
@@ -129,6 +147,8 @@ public inline fun <T, K> compareByDescending(comparator: Comparator<in K>, cross
|
||||
/**
|
||||
* Creates a comparator comparing values after the primary comparator defined them equal. It uses
|
||||
* the function to transform value to a [Comparable] instance for comparison.
|
||||
*
|
||||
* @sample samples.comparisons.Comparisons.thenBy
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T> Comparator<T>.thenBy(crossinline selector: (T) -> Comparable<*>?): Comparator<T> =
|
||||
@@ -140,6 +160,8 @@ public inline fun <T> Comparator<T>.thenBy(crossinline selector: (T) -> Comparab
|
||||
/**
|
||||
* Creates a comparator comparing values after the primary comparator defined them equal. It uses
|
||||
* the [selector] function to transform values and then compares them with the given [comparator].
|
||||
*
|
||||
* @sample samples.comparisons.Comparisons.thenByWithComparator
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T, K> Comparator<T>.thenBy(comparator: Comparator<in K>, crossinline selector: (T) -> K): Comparator<T> =
|
||||
@@ -151,6 +173,8 @@ public inline fun <T, K> Comparator<T>.thenBy(comparator: Comparator<in K>, cros
|
||||
/**
|
||||
* Creates a descending comparator using the primary comparator and
|
||||
* the function to transform value to a [Comparable] instance for comparison.
|
||||
*
|
||||
* @sample samples.comparisons.Comparisons.thenByDescending
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T> Comparator<T>.thenByDescending(crossinline selector: (T) -> Comparable<*>?): Comparator<T> =
|
||||
@@ -162,6 +186,8 @@ public inline fun <T> Comparator<T>.thenByDescending(crossinline selector: (T) -
|
||||
/**
|
||||
* Creates a descending comparator comparing values after the primary comparator defined them equal. It uses
|
||||
* the [selector] function to transform values and then compares them with the given [comparator].
|
||||
*
|
||||
* @sample samples.comparisons.Comparisons.thenByDescendingWithComparator
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T, K> Comparator<T>.thenByDescending(comparator: Comparator<in K>, crossinline selector: (T) -> K): Comparator<T> =
|
||||
@@ -173,6 +199,8 @@ public inline fun <T, K> Comparator<T>.thenByDescending(comparator: Comparator<i
|
||||
|
||||
/**
|
||||
* Creates a comparator using the primary comparator and function to calculate a result of comparison.
|
||||
*
|
||||
* @sample samples.comparisons.Comparisons.thenComparator
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T> Comparator<T>.thenComparator(crossinline comparison: (a: T, b: T) -> Int): Comparator<T> =
|
||||
@@ -184,6 +212,8 @@ public inline fun <T> Comparator<T>.thenComparator(crossinline comparison: (a: T
|
||||
/**
|
||||
* Combines this comparator and the given [comparator] such that the latter is applied only
|
||||
* when the former considered values equal.
|
||||
*
|
||||
* @sample samples.comparisons.Comparisons.then
|
||||
*/
|
||||
public infix fun <T> Comparator<T>.then(comparator: Comparator<in T>): Comparator<T> =
|
||||
Comparator { a, b ->
|
||||
@@ -194,6 +224,8 @@ public infix fun <T> Comparator<T>.then(comparator: Comparator<in T>): Comparato
|
||||
/**
|
||||
* Combines this comparator and the given [comparator] such that the latter is applied only
|
||||
* when the former considered values equal.
|
||||
*
|
||||
* @sample samples.comparisons.Comparisons.thenDescending
|
||||
*/
|
||||
public infix fun <T> Comparator<T>.thenDescending(comparator: Comparator<in T>): Comparator<T> =
|
||||
Comparator<T> { a, b ->
|
||||
@@ -205,6 +237,8 @@ public infix fun <T> Comparator<T>.thenDescending(comparator: Comparator<in T>):
|
||||
/**
|
||||
* Extends the given [comparator] of non-nullable values to a comparator of nullable values
|
||||
* considering `null` value less than any other value.
|
||||
*
|
||||
* @sample samples.comparisons.Comparisons.nullsFirstLastWithComparator
|
||||
*/
|
||||
public fun <T: Any> nullsFirst(comparator: Comparator<in T>): Comparator<T?> =
|
||||
Comparator { a, b ->
|
||||
@@ -219,6 +253,8 @@ public fun <T: Any> nullsFirst(comparator: Comparator<in T>): Comparator<T?> =
|
||||
/**
|
||||
* Provides a comparator of nullable [Comparable] values
|
||||
* considering `null` value less than any other value.
|
||||
*
|
||||
* @sample samples.comparisons.Comparisons.nullsFirstLastComparator
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T: Comparable<T>> nullsFirst(): Comparator<T?> = nullsFirst(naturalOrder())
|
||||
@@ -226,6 +262,8 @@ public inline fun <T: Comparable<T>> nullsFirst(): Comparator<T?> = nullsFirst(n
|
||||
/**
|
||||
* Extends the given [comparator] of non-nullable values to a comparator of nullable values
|
||||
* considering `null` value greater than any other value.
|
||||
*
|
||||
* @sample samples.comparisons.Comparisons.nullsFirstLastWithComparator
|
||||
*/
|
||||
public fun <T: Any> nullsLast(comparator: Comparator<in T>): Comparator<T?> =
|
||||
Comparator { a, b ->
|
||||
@@ -240,21 +278,31 @@ public fun <T: Any> nullsLast(comparator: Comparator<in T>): Comparator<T?> =
|
||||
/**
|
||||
* Provides a comparator of nullable [Comparable] values
|
||||
* considering `null` value greater than any other value.
|
||||
*
|
||||
* @sample samples.comparisons.Comparisons.nullsFirstLastComparator
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T: Comparable<T>> nullsLast(): Comparator<T?> = nullsLast(naturalOrder())
|
||||
|
||||
/**
|
||||
* Returns a comparator that compares [Comparable] objects in natural order.
|
||||
*
|
||||
* @sample samples.comparisons.Comparisons.naturalOrderComparator
|
||||
*/
|
||||
public fun <T: Comparable<T>> naturalOrder(): Comparator<T> = @Suppress("UNCHECKED_CAST") (NaturalOrderComparator as Comparator<T>)
|
||||
|
||||
/**
|
||||
* Returns a comparator that compares [Comparable] objects in reversed natural order.
|
||||
*
|
||||
* @sample samples.comparisons.Comparisons.nullsFirstLastWithComparator
|
||||
*/
|
||||
public fun <T: Comparable<T>> reverseOrder(): Comparator<T> = @Suppress("UNCHECKED_CAST") (ReverseOrderComparator as Comparator<T>)
|
||||
|
||||
/** Returns a comparator that imposes the reverse ordering of this comparator. */
|
||||
/**
|
||||
* Returns a comparator that imposes the reverse ordering of this comparator.
|
||||
*
|
||||
* @sample samples.comparisons.Comparisons.reversed
|
||||
*/
|
||||
public fun <T> Comparator<T>.reversed(): Comparator<T> = when (this) {
|
||||
is ReversedComparator -> this.comparator
|
||||
NaturalOrderComparator -> @Suppress("UNCHECKED_CAST") (ReverseOrderComparator as Comparator<T>)
|
||||
|
||||
Reference in New Issue
Block a user