Kotlin 中的平等

Equality in Kotlin

提问人:Dabbler 提问时间:8/19/2017 最后编辑:Dabbler 更新时间:1/20/2022 访问量:32066

问:

我正在学习Kotlin,具有C++和Java背景。我期待打印以下内容,而不是.我知道映射到 .是否默认实现不比较每个成员,即 和?如果是这样,它不会将字符串值视为相等(因为再次映射到)?显然,在Kotlin中,我还没有弄清楚与平等与身份有关的东西。truefalse==equalsequalsfirstNamelastName==equals

class MyPerson(val firstName: String, val lastName: String)

fun main(args: Array<String>) {
   println(MyPerson("Charlie", "Parker") == MyPerson("Charlie", "Parker"))
}
java 运算符重载 kotlin 运算符 相等

评论


答:

25赞 JB Nizet 8/19/2017 #1

您描述的默认实现仅存在于数据类中。不适用于实现继承自 的常规类,只需使对象等于自身。equalsAny

评论

8赞 stdout 4/5/2019
因此,如果 equals 没有被常规类覆盖,则本质上与调用 === 相同。
1赞 Sam Chen 11/29/2020
@stdout 这正是我正在寻找的答案。
61赞 s1m0nw1 8/20/2017 #2

参照相等

爪哇岛

在 Java 中,比较变量引用的默认实现总是这样做:equals==

类的方法实现了最具区分性的 对象上可能的等价关系;也就是说,对于任何非 null 引用值 x 和 y,此方法返回当且仅当 x 和 y 引用同一对象(具有值)。equalsObjecttruex == ytrue

我们称之为“参照平等”。

Kotlin

在 Kotlin 中被编译为 ,而相当于 Java 的 .==equals=====

结构平等

每当我们想要结构性而不是引用性相等时,我们都可以覆盖 ,正如您所建议的那样,默认情况下,普通永远不会这样做。在 Kotlin 中,我们可以使用 ,编译器会根据构造函数属性自动创建实现(阅读此处)。equalsdata class

请记住,如果您手动覆盖(反之亦然),请始终覆盖,并遵守两种方法的非常严格的约定。Kotlin 的编译器生成的实现确实满足了合同要求。hashCodeequals

评论

2赞 Gastón Saillén 4/25/2019
在 kotlin 中,您可以 ctrl + 单击运算符,您会看到它与此答案相同的内容,如果您 ctrl + 单击该方法,您还将看到指向相同实现的链接。==equalsequals
17赞 TooCool 8/20/2017 #3

== 平等

在 Java 中,可以使用 == 来比较原始类型和引用类型。如果应用于基元类型,Java 的 == 比较值,而引用类型的 == 比较引用。因此,在 Java 中,有一个众所周知的做法,即总是调用 equals,并且有一个众所周知的忘记这样做的问题。

在 Kotlin 中,== 是比较两个对象的默认方式:它通过在后台调用 equals 来比较它们的值。因此,如果 equals 在您的类中被覆盖,则可以使用 == 安全地比较其实例。对于引用比较,您可以使用 === 运算符,它的工作方式与 Java 中的 == 完全相同。

class MyPerson(val firstName: String, val lastName: String){
    override fun equals(other: Any?): Boolean {
        if (other == null || other !is MyPerson) return false
        return firstName == other.firstName && lastName == other.lastName
    }
}

fun main(args: Array<String>) {
    println(MyPerson("Charlie", "Parker") == MyPerson("Charlie", "Parker")) // print "true"
}

在您的例子中,用于自动生成通用方法(、 和 )的实现。MyPersondata classtoStringequalshashCode