Kotlin排序指南

Guide to Sorting in Kotlin

1.概述

Kotlin使用扩展方法在Java Collection框架之上构建。 这极大地提高了可用性和可读性,而无需诸如Apache Commons或Guava之类的第三方依赖项。

在本教程中,我们将重点介绍Kotlin中的排序。 另外,我们将使用kotlin.comparisons包来实现复杂的排序规则。

2.对集合进行排序

Kotlin提供了多种实用程序,可简化对集合进行排序的过程。 让我们探索其中的几种方法。

2.1。 分类

对集合进行排序的最简单方法是调用sort方法。 此方法将使用元素的自然顺序。 另外,默认情况下它将按升序排列,因此'a'在'b'之前,'1'在'2'之前:

1
2
3
val sortedValues = mutableListOf(1, 2, 7, 6, 5, 6)
sortedValues.sort()
println(sortedValues)

以上代码的结果是:

1
[1, 2, 5, 6, 6, 7]

重要的是要注意,我们使用了可变的集合。 原因是sort方法将就地排序。 如果我们希望将结果作为新列表返回,则只需要使用sorted方法即可。

此外,我们可以使用sortDescending或reverse方法以降序排序。

2.2。 排序方式

如果需要按给定对象的特定属性进行排序,则可以使用sortBy.sortBy方法允许我们将选择器函数作为参数传递。 选择器函数将接收该对象,并应返回我们要排序的值:

1
2
3
val sortedValues = mutableListOf(1 to"a", 2 to"b", 7 to"c", 6 to"d", 5 to"c", 6 to"e")
sortedValues.sortBy { it.second }
println(sortedValues)

以上代码的结果是:

1
[(1, a), (2, b), (7, c), (5, c), (6, d), (6, e)]

同样,集合必须是可变的,因为sortBy方法将就地排序。 如果希望将结果作为新列表返回,则需要使用sortedBy方法而不是sortBy方法。

像以前一样,对于降序,我们可以使用sortByDescending或reverse方法。

2.3。 SortWith

对于更高级的用法(例如,结合多个规则),我们可以使用sortWith方法。

我们可以将Comparator对象作为参数传递。 在Kotlin中,我们有多种创建Comparator对象的方法,我们将在下一部分中进行介绍:

1
2
3
val sortedValues = mutableListOf(1 to"a", 2 to"b", 7 to"c", 6 to"d", 5 to"c", 6 to"e")
sortedValues.sortWith(compareBy({it.second}, {it.first}))
println(sortedValues)

以上代码的结果是,它们按字母然后按数字排序:

1
[(1, a), (2, b), (5, c), (7, c), (6, d), (6, e)]

因为sortWith会就地进行排序,所以我们需要使用可变的集合。 如果我们希望将结果作为新的集合返回,则需要使用sortedWith方法而不是sortWith方法。

对于降序,我们可以使用反向方法,也可以定义rightComparator。

3.比较

Kotlin包含一个非常有用的软件包来构建比较器– kotlin.comparisons。在以下各节中,我们将讨论:

  • 比较器创建

  • 空值的处理

  • 冲销订单

  • 比较器规则扩展

  • 3.1。 比较器创建

    为了简化我们的Comparator的创建,Kotlin引入了许多工厂方法来使我们的代码更具表现力。

    可用的最简单的Comparator工厂是naturalOrder()。 不需要参数,默认情况下顺序是升序的:

    1
    val ascComparator = naturalOrder<Long>()

    对于具有多个属性的对象,我们可以使用compareBy方法。 作为参数,我们提供了可变数量的函数(排序规则),每个函数将返回一个Comparable对象。 然后,将依次调用这些函数,直到得到的Comparable对象评估为不相等或直到调用了所有函数为止。

    在下一个示例中,it.first值用于比较,仅当值相等时,才会调用it.second打破平局:

    1
    val complexComparator = compareBy<Pair<Int, String?>>({it.first}, {it.second})

    随时浏览kotlin.comparisons,以发现所有可用的工厂。

    3.2。 空值的处理

    使用null值处理来改进ourComparator的一种简单方法是使用nullsFirst或nullsLast方法。 这些方法将分别对空值排序在第一位或最后一位:

    1
    2
    3
    val sortedValues = mutableListOf(1 to"a", 2 to null, 7 to"c", 6 to"d", 5 to"c", 6 to"e")
    sortedValues.sortWith(nullsLast(compareBy { it.second }))
    println(sortedValues)

    上面代码的结果将是:

    1
    [(1, a), (7, c), (5, c), (6, d), (6, e), (2, null)]

    我们可以看到结果集合中的最后一个值是具有空值的那个。

    3.3。 冲销订单

    要颠倒顺序,我们可以使用reverseOrder方法或reversed方法。 前一种方法没有参数,并返回降序排列。 可以将后一种方法应用于Comparator对象,并将返回其反向的Comparator对象。

    要使用降序自然顺序构建比较器,我们可以执行以下操作:

    1
    reverseOrder()

    3.4。 比较器规则扩展

    可以通过kotlin.comparable软件包中提供的then方法将比较器对象与其他排序规则组合或扩展。

    仅当第一个比较器的评估结果相等时,才使用第二个比较器。

    我们的学生名单包含每个人的年龄和姓名。 我们希望它们从最小到最大排序,并且在它们相同的年龄时,根据名称降序排列:

    1
    2
    3
    4
    5
    val students = mutableListOf(21 to"Helen", 21 to"Tom", 20 to"Jim")

    val ageComparator = compareBy<Pair<Int, String?>> {it.first}
    val ageAndNameComparator = ageComparator.thenByDescending {it.second}
    println(students.sortedWith(ageAndNameComparator))

    上面代码的结果将是:

    1
    [(20, Jim), (21, Tom), (21, Helen)]

    4。结论

    在本快速教程中,我们了解了如何使用sort,sortBy和sortWith方法对Kotlin中的集合进行排序。

    后来,我们还使用了kotlin.comparisons包来创建Comparator对象,并使用其他排序规则对其进行增强。

    所有这些示例和代码片段的实现都可以在GitHub上找到。