0Pricing
Kotlin Academy · 课时

比较运算符

compareTo 与 equals

比较运算符 是 CoddyKit 上的免费 Kotlin Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Kotlin Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Kotlin Academy 课程共包含 4 节课。

比较自定义类型

若要在您的类型上使用 <、>、<=、>=,请定义一个返回 Int 的 operator fun compareTo。

data class Money(val cents: Int) {
    operator fun compareTo(o: Money) = cents - o.cents
}

fun main() {
    println(Money(500) > Money(200))
}

compareTo 契约

如果接收者较小,compareTo 返回负数;如果相等,返回零;如果较大,则返回正数。

data class Version(val n: Int) {
    operator fun compareTo(o: Version) = n - o.n
}

fun main() {
    println(Version(2).compareTo(Version(5)))
}

实现 Comparable

实现 Comparable<T> 接口是符合惯用风格的做法;它的 compareTo 已经是一个运算符。

data class Score(val value: Int) : Comparable<Score> {
    override fun compareTo(other: Score) = value - other.value
}

fun main() {
    println(Score(10) < Score(20))
}

使用 Comparable 排序

类型实现 Comparable 后,sorted() 等集合函数就可以自动工作。

data class Player(val rank: Int) : Comparable<Player> {
    override fun compareTo(other: Player) = rank - other.rank
}

fun main() {
    val sorted = listOf(Player(3), Player(1), Player(2)).sorted()
    println(sorted.map { it.rank })
}

使用 compareValuesBy

对于涉及多个字段的比较,compareValuesBy 会按照选择器的顺序逐个进行比较。

data class Person(val age: Int, val name: String) : Comparable<Person> {
    override fun compareTo(other: Person) =
        compareValuesBy(this, other, { it.age }, { it.name })
}

fun main() {
    println(Person(30, "Al") < Person(30, "Bo"))
}

使用 equals 判断相等

== 运算符调用的是 equals,而不是 compareTo。重写 equals 即可控制值相等的判断方式。

class Id(val value: Int) {
    override fun equals(other: Any?) =
        other is Id && other.value == value
    override fun hashCode() = value
}

fun main() {
    println(Id(7) == Id(7))
}

equals 与 hashCode 的配合

如果重写了 equals,也必须重写 hashCode,这样相等的对象才会共享同一个哈希值,从而确保基于哈希的集合工作正常。

class Tag(val name: String) {
    override fun equals(other: Any?) = other is Tag && other.name == name
    override fun hashCode() = name.hashCode()
}

fun main() {
    val set = hashSetOf(Tag("a"), Tag("a"))
    println(set.size)
}

数据类会自动完成这些工作

data class 会根据属性自动生成 equals 和 hashCode,因此 == 会按值进行比较。

data class Coord(val x: Int, val y: Int)

fun main() {
    println(Coord(1, 2) == Coord(1, 2))
}

相等性与身份

== 会调用 equals(值相等);=== 会检查引用身份。两者可能得出不同结果。

data class Box(val n: Int)

fun main() {
    val a = Box(1)
    val b = Box(1)
    println(a == b)
    println(a === b)
}

在条件中进行比较

定义了 compareTo 后,您的类型就可以像数字一样在 if 和 when 中使用。

data class Weight(val g: Int) : Comparable<Weight> {
    override fun compareTo(other: Weight) = g - other.g
}

fun main() {
    val w = Weight(50)
    println(if (w > Weight(40)) "heavy" else "light")
}

maxOf 与 minOf

可比较类型可以与 maxOf 和 minOf 一起使用。

data class T(val v: Int) : Comparable<T> {
    override fun compareTo(other: T) = v - other.v
}

fun main() {
    println(maxOf(T(3), T(8)).v)
}

快速检查

请测试您对比较运算符的理解。

回顾

您了解了比较运算符:

  • compareTo 为 <、>、<=、>= 提供实现,并返回负数、零或正数。
  • 实现 Comparable<T>,即可按照惯用方式进行排序和比较。
  • == 使用 equals;请始终将它与 hashCode 配合使用。
  • 数据类会自动生成 equals 和 hashCode。
data class S(val v: Int) : Comparable<S> {
    override fun compareTo(other: S) = v - other.v
}

fun main() {
    println(S(2) < S(5))
}

常见问题解答

「比较运算符」课时是免费的吗?

是的 — 「比较运算符」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Kotlin Academy 课程的其余内容,请升级到 CoddyKit PRO。 Kotlin Academy 课程共包含 4 节课。

「比较运算符」这节课中我会学到什么?

compareTo 与 equals 你通过在浏览器中直接运行的动手代码来练习 Kotlin Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Kotlin Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Kotlin Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「比较运算符」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Kotlin Academy 课中编写并运行代码吗?

能。每节 Kotlin Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 运算符函数
  2. 比较运算符
  3. 索引与调用
  4. 最佳实践
← 返回 Kotlin Academy