added a couple of helper functions to make it easier to compare values, implement Comparable and create Comparators
This commit is contained in:
@@ -95,15 +95,7 @@ class KDocConfig() {
|
|||||||
|
|
||||||
protected class LongestFirstStringComparator() : Comparator<String> {
|
protected class LongestFirstStringComparator() : Comparator<String> {
|
||||||
override fun compare(s1: String?, s2: String?): Int {
|
override fun compare(s1: String?, s2: String?): Int {
|
||||||
// TODO could we make this kind of code much easier?
|
return compareBy(s1, s2, { (s: String) -> s.length() })
|
||||||
if (s1 == s2) return 0
|
|
||||||
if (s1 == null) return -1
|
|
||||||
if (s2 == null) return 1
|
|
||||||
var answer = s1.length() - s2.length()
|
|
||||||
if (answer == 0) {
|
|
||||||
answer = s1.compareTo(s2)
|
|
||||||
}
|
|
||||||
return answer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun equals(obj : Any?) : Boolean {
|
override fun equals(obj : Any?) : Boolean {
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package kotlin
|
||||||
|
|
||||||
|
import java.lang.Iterable
|
||||||
|
import java.util.Comparator
|
||||||
|
import java.util.Comparator
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for implementing [[Comparable<T>]] methods using a list of functions
|
||||||
|
* to calculate the values to compare
|
||||||
|
*/
|
||||||
|
inline fun <T> compareBy(a: T?, b: T?, vararg functions: Function1<T,Any?>): Int {
|
||||||
|
if (a === b) return 0
|
||||||
|
if (a == null) return - 1
|
||||||
|
if (b == null) return 1
|
||||||
|
for (fn in functions) {
|
||||||
|
val v1 = fn(a)
|
||||||
|
val v2 = fn(b)
|
||||||
|
val diff = compareValues(v1, v2)
|
||||||
|
if (diff != null) return diff
|
||||||
|
}
|
||||||
|
return compareValues(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares the two values which may be [[Comparable]] otherwise
|
||||||
|
* the [[#hashCode()]] method is used as the difference
|
||||||
|
*/
|
||||||
|
inline fun <T> compareValues(a: T?, b: T?): Int {
|
||||||
|
if (a == null) return - 1
|
||||||
|
if (b == null) return 1
|
||||||
|
if (a is Comparable<T>) {
|
||||||
|
return a.compareTo(b)
|
||||||
|
}
|
||||||
|
if (a == b) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if (a is Object && b is Object) {
|
||||||
|
val diff = a.hashCode() - b.hashCode()
|
||||||
|
return if (diff == 0) 1 else diff
|
||||||
|
} else {
|
||||||
|
// TODO???
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a comparator using the sequence of functions used to calcualte a value to compare on
|
||||||
|
*/
|
||||||
|
inline fun <T> comparator(vararg functions: Function1<T,Any?>): Comparator<T> {
|
||||||
|
return FunctionComparator<T>(functions)
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FunctionComparator<T>(val functions: Array<Function1<T,Any?>>): Comparator<T> {
|
||||||
|
|
||||||
|
fun toString(): String {
|
||||||
|
return "FunctionComparator${functions.toList()}"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun compare(o1: T?, o2: T?): Int {
|
||||||
|
// TODO compile error
|
||||||
|
//return compareBy<T>(o1, o2, functions)
|
||||||
|
throw UnsupportedOperationException("TODO")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(obj: Any?): Boolean {
|
||||||
|
return this == obj
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
|
class Item(val name: String, val rating: Int)
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
class CompareTest {
|
||||||
|
val v1 = Item("wine", 9)
|
||||||
|
val v2 = Item("beer", 10)
|
||||||
|
|
||||||
|
Test fun compareByNameFirst() {
|
||||||
|
val diff = compareBy(v1, v2, {(i: Item) -> i.name}, {(i: Item) -> i.rating})
|
||||||
|
assertTrue(diff > 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
Test fun compareByRatingFirst() {
|
||||||
|
val diff = compareBy(v1, v2, {(i: Item) -> i.rating}, {(i: Item) -> i.name})
|
||||||
|
assertTrue(diff < 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
Test fun compareSameObjectsByRatingFirst() {
|
||||||
|
val diff = compareBy(v1, v1, {(i: Item) -> i.rating}, {(i: Item) -> i.name})
|
||||||
|
assertTrue(diff == 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
Test fun createComparator() {
|
||||||
|
val c = comparator({(i: Item) -> i.rating}, {(i: Item) -> i.name})
|
||||||
|
println("Created comparator $c")
|
||||||
|
/*
|
||||||
|
val items = arrayList(v1, v2)
|
||||||
|
items.sort(c)
|
||||||
|
println("Sorted list in rating order $items")
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user