Kotlin:使用T作为类,对List<T>进行排序

4
我在Kotlin中定义了一个公共类:public class Edge(val v: Int, val u: Int, val weight: Double),用于定义图的加权边。
现在,在另一个类中,我需要创建一个列表,我将其定义为 var Sides = mutableListOf<Edge>(),但我需要按照第三个参数(即weight)的升序对该列表进行排序。如果我有以下列表:
Sides = {Edge(4, 8, 4.1), Edge(20, 9, 7.5), Edge(5, 4, 0.0)}
则它会变成:
Sides = {Edge(5, 4, 0.0), Edge(4, 8, 4.1), Edge(20, 9, 7.5)}
是否有像.sort()这样的函数可以用来对此列表进行排序?还是我必须手动编写一个排序方法的函数?
谢谢。
3个回答

4
对于像MutableList这样的可变集合,您可以使用sortBy函数对原始列表进行排序。
sides.sortBy { it.weight }

如果您有一个不可变的集合,比如 List,您可以使用 sortedBy 函数来返回一个新的按照排序后的列表。

val sortedList = sides.sortedBy { it.weight }

此外,你还可以使用 sortByDescendingsortedByDescending 对内容进行降序排序。


3
你需要的是 sortBy。给定一个 T 类型的列表,sortBy 函数接受一个从 T 映射到 R(其中 R 是某个具有排序定义的类型)的映射函数。考虑使用该函数来进行排序。
Sides.sortBy { n -> n.weight }

3
你有两种基本方法:
  1. Edge 赋予一个 自然排序。这样所有的排序函数都会默认使用它,包括任何可以使用排序的情况(例如 SortedMap 中键的顺序和 binarySearch() 方法)。

你可以通过实现Comparable接口来实现自然排序。该接口只有一个方法 compareTo(),可能很简单,如下所示:

public class Edge(val v: Int, val u: Int, val weight: Double) : Comparable<Edge> {
    override fun compareTo(other: Edge) = weight.compareTo(other.weight)
}

然而,这并不能为具有相同权重的实例提供一致的排序,因此您可能还想使用其他属性作为解决平局的方法,例如:

    override fun compareTo(other: Edge)
        = weight.compareTo(other.weight).takeIf{ it != 0 }
        ?: v.compareTo(other.v).takeIf{ it != 0 }
        ?: u.compareTo(other.u)

在实现此功能时有一些微妙之处,尤其是如果您没有直接覆盖 equals() 方法。阅读Java文档会很有帮助。

请注意,data class 会自动实现 Comparable 接口,使用其构造函数中的属性,并按照它们的顺序进行排序,因此通常不需要为此担心排序问题。

  1. 在排序时提供一个顺序

其他答案已经讨论了这个问题。可能最简单的方法是:

sides.sortBy{ it.weight }

虽然有许多替代方案,比如:

sides.sortWith{ a, b -> a.weight.compareTo(b.weight) }

或者您可以创建一个可根据需要重用的Comparator实例:

val comparator = Comparator<Edge>{ o1, o2 -> o1.weight.compareTo(o2.weight) }
sides.sortWith(comparator)

再次提醒,许多标准库中的函数都可以使用比较器,因此您可以避免重复编写权重比较代码。


选择哪种方法取决于您的需求。

如果按权重排序对于您的边始终有直观意义,则自然排序是一个很好的选择。这样的话,您只需要在一个地方实现Comparable 或将您的类作为data class,并将权重属性指定为首个属性,就可以获得全面的排序优势。(当然,只有在您控制Edge源代码时才能这样做。)

另一方面,如果按权重排序仅适用于特定方法 - 如果您可能希望在其他地方使用不同的排序方式 - 那么在排序时指定排序顺序会更合理。

当然,如果需要,您可以同时进行两种操作:为大多数操作给出自然排序,但是针对特定操作指定不同的排序顺序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接