Introduce naturalOrder<T> and reverseOrder<T> comparators.

This commit is contained in:
Ilya Gorbunov
2015-10-31 07:58:11 +03:00
parent 83fef68876
commit 2b676e08bc
2 changed files with 43 additions and 4 deletions
+21 -1
View File
@@ -75,7 +75,7 @@ public fun <T : Comparable<*>> compareValues(a: T?, b: T?): Int {
if (a == null) return -1
if (b == null) return 1
return (a as Comparable<Any?>).compareTo(b)
return (a as Comparable<Any>).compareTo(b)
}
/**
@@ -293,9 +293,21 @@ public fun <T: Comparable<T>> nullsLast(): Comparator<T?> {
}
}
/**
* Returns a comparator that compares [Comparable] objects in natural order.
*/
public fun <T: Comparable<T>> naturalOrder(): Comparator<T> = NaturalOrderComparator as Comparator<T>
/**
* Returns a comparator that compares [Comparable] objects in reversed natural order.
*/
public fun <T: Comparable<T>> reverseOrder(): Comparator<T> = ReverseOrderComparator as Comparator<T>
/** Returns a comparator that imposes the reverse ordering of this comparator. */
public fun <T> Comparator<T>.reversed(): Comparator<T> = when (this) {
is ReversedComparator -> this.comparator
NaturalOrderComparator -> ReverseOrderComparator as Comparator<T>
ReverseOrderComparator -> NaturalOrderComparator as Comparator<T>
else -> ReversedComparator(this)
}
@@ -303,3 +315,11 @@ public fun <T> Comparator<T>.reversed(): Comparator<T> = when (this) {
private class ReversedComparator<T>(public val comparator: Comparator<T>): Comparator<T> {
override fun compare(a: T, b: T): Int = comparator.compare(b, a)
}
private object NaturalOrderComparator : Comparator<Comparable<Any>> {
override fun compare(c1: Comparable<Any>, c2: Comparable<Any>): Int = c1.compareTo(c2)
}
private object ReverseOrderComparator: Comparator<Comparable<Any>> {
override fun compare(c1: Comparable<Any>, c2: Comparable<Any>): Int = c2.compareTo(c1)
}
+22 -3
View File
@@ -50,7 +50,7 @@ class OrderingTest {
@Test
fun sortComparatorThenComparator() {
val comparator = comparator<Item> { a, b -> a.name.compareTo(b.name) } thenComparator { a, b -> a.rating.compareTo(b.rating) }
val comparator = comparator<Item> { a, b -> a.name.compareTo(b.name) }.thenComparator { a, b -> a.rating.compareTo(b.rating) }
val diff = comparator.compare(v1, v2)
assertTrue(diff > 0)
@@ -74,9 +74,28 @@ class OrderingTest {
assertTrue( (byRating thenDescending byName).compare(v4, v2) < 0 )
}
@Test
fun reversedComparator() {
val comparator = compareBy<Item> { it.name }
val reversed = comparator.reversed()
assertEquals(comparator.compare(v2, v1), reversed.compare(v1, v2))
assertEquals(comparator, reversed.reversed())
}
@Test
fun naturalOrderComparator() {
val v1 = "a"
val v2 = "beta"
assertTrue(naturalOrder<String>().compare(v1, v2) < 0)
assertTrue(reverseOrder<String>().compare(v1, v2) > 0)
assertTrue(reverseOrder<Int>() === naturalOrder<Int>().reversed())
assertTrue(naturalOrder<Int>() === reverseOrder<Int>().reversed())
}
@Test
fun sortByThenBy() {
val comparator = compareBy<Item> { it.rating } thenBy { it.name }
val comparator = compareBy<Item> { it.rating }.thenBy { it.name }
val diff = comparator.compare(v1, v2)
assertTrue(diff < 0)
@@ -87,7 +106,7 @@ class OrderingTest {
@Test
fun sortByThenByDescending() {
val comparator = compareBy<Item> { it.rating } thenByDescending { it.name }
val comparator = compareBy<Item> { it.rating }.thenByDescending { it.name }
val diff = comparator.compare(v1, v2)
assertTrue(diff < 0)