📜  Kotlin 中的比较器

📅  最后修改于: 2022-05-13 01:54:35.267000             🧑  作者: Mango

Kotlin 中的比较器

在编程上下文中,随着对新类型的需求的出现,还有一项主要任务是对类型的实例进行排序。为了比较一个类型的两个实例,我们实现了 Comparable 接口。但是,由于在排序实例时必须自动比较它们,而且顺序可以根据各种参数而变化,所以 Kotlin 提供了一个简单的Comparator 接口。该接口比较一个类型的两个对象并按顺序排列它们。

函数——

compare:此函数比较一个类型的两个实例,如果两者相等则返回零,如果第二个实例较大则返回负数,否则返回正数。

abstract fun compare(a: T, b: T): Int

扩展功能 –

reversed:此函数将比较器作为参数,并返回与传递的比较器顺序相反的比较器。

fun  Comparator.reversed(): Comparator


then:此函数结合了两个比较器,只有在根据第一个比较器的值相等时才使用第二个。

infix fun  Comparator.then(
    comparator: Comparator
): Comparator

演示比较、然后和反转功能的示例。

// A simple class to represent a name
class Name(val firstName: String,val lastName: String){
    override fun toString(): String {
        return """$firstName $lastName"""
    }
}
   
// A comparator to compare first names of Name
class ComparatorOne: Comparator{
    override fun compare(o1: Name?, o2: Name?): Int {
        if(o1 == null || o2 == null){
            return 0;
        }
        return o1.firstName.compareTo(o2.firstName)
    }
}
   
// A comparator to compare last names of Name
class AnotherComparator: Comparator{
    override fun compare(o1: Name?, o2: Name?): Int {
        if(o1 == null || o2 == null)
            return 0
        return o1.lastName.compareTo(o2.lastName)
    }
}
   
fun main(){
    val list = ArrayList()
    list.add(Name("Steve","Waugh"))
    list.add(Name("Steve","Smith"))
    list.add(Name("Virat","Kohli"))
    list.add(Name("Kane","Williamson"))
    list.add(Name("Joe","Root"))
   
    println("The list is:")
    println(list)
   
    val comparatorOne = ComparatorOne()
    // Sorting list according to first names
    list.sortWith(comparatorOne)
    println("List sorted according to first name")
    println(list)
   
    val anotherComparator = AnotherComparator()
    val finalComparator = comparatorOne.then(anotherComparator)
    // Sorting list according to first name then by last name
    list.sortWith(finalComparator)
    println("List sorted according to first name and last name")
    println(list)
   
    val reverseComparator = finalComparator.reversed()
    // Reverse sorting the list
    list.sortWith(reverseComparator)
    println("List reverse sorted")
    println(list)
}

输出:

The list is:
[Steve Waugh, Steve Smith, Virat Kohli, Kane Williamson, Joe Root]
List sorted according to first name
[Joe Root, Kane Williamson, Steve Waugh, Steve Smith, Virat Kohli]
List sorted according to first name and last name
[Joe Root, Kane Williamson, Steve Smith, Steve Waugh, Virat Kohli]
List reverse sorted
[Virat Kohli, Steve Waugh, Steve Smith, Kane Williamson, Joe Root]

thenBy:此函数将类型实例转换为 Comparable 类型的实例,然后使用这些实例进行比较。

fun  Comparator.thenBy(
    selector: (T) -> Comparable<*>?
): Comparator


thenByDescending:此函数返回一个降序比较器,它将一个值转换为 Comparable 类型的实例,然后比较这些实例。

inline fun  Comparator.thenByDescending(
    crossinline selector: (T) -> Comparable<*>?
): Comparator

演示 thenBy 和 thenByDescending 函数的示例

class Person(val height: Int,val weight: Int){
    override fun toString(): String {
        return "Height = ${height}, Weight = ${weight}"
    }
}
   
fun main() {
    val comparator = compareBy { it.height }
    val list = listOf(
        Person(4, 10),
        Person(2, 10),
        Person(3, 45),
        Person(3, 25),
        Person(7, 95),
        Person(5, 50)
    )
   
    println("Sorted first according to height then by weight")
    val anotherComparator = comparator.thenBy { it.weight }
    println(list.sortedWith(anotherComparator))
   
    println("Sorted first according to weight then by descending order in height")
    val comparator2 = compareBy { it.weight }.thenByDescending { it.height }
    println(list.sortedWith(comparator2))
}

输出:

Sorted first according to height then by weight
[Height = 2, Weight = 10, Height = 3, Weight = 25, Height = 3, Weight = 45, Height = 4, Weight = 10, Height = 5, Weight = 50, Height = 7, Weight = 95]
Sorted first according to weight then by descending order in height
[Height = 4, Weight = 10, Height = 2, Weight = 10, Height = 3, Weight = 25, Height = 3, Weight = 45, Height = 5, Weight = 50, Height = 7, Weight = 95]


thenComparator:此函数返回一个 Comparator,它使用主 Comparator 和一个函数来执行比较。

fun  Comparator.thenComparator(
    comparison: (a: T, b: T) -> Int
): Comparator


thenDescending:该函数结合了两个比较器,第二个比较器仅在根据第一个比较器的值相等时使用,并按降序对元素进行排序。

infix fun  Comparator.thenDescending(
    comparator: Comparator
): Comparator

演示 thenComparator 和 thenDescending 函数的示例。

fun main(){
    val list = listOf>(
        Pair("A",3),
        Pair("B",1),
        Pair("G",345),
        Pair("E",20),
        Pair("A",0),
        Pair("J",0)
    )
   
    val comparator = compareBy> { it.first }
        .thenComparator({a,b -> compareValues(a.second,b.second)})
   
    println("Pairs sorted by String then by Integers")
    println(list.sortedWith(comparator))
   
    val anotherComparator = compareBy> { it.second }
    val anotherComparator2 = compareBy>{it.first}
    println("Pairs sorted by Integers then by Strings in Descending order")
    println(list.sortedWith(anotherComparator.thenDescending(anotherComparator2)))
}

输出:

Pairs sorted by String then by Integers
[(A, 0), (A, 3), (B, 1), (E, 20), (G, 345), (J, 0)]
Pairs sorted by Integers then by Strings in Descending order
[(J, 0), (A, 0), (B, 1), (A, 3), (E, 20), (G, 345)]