科特林的平等

时间:2017-08-19 14:54:47

标签: java operator-overloading kotlin operators equality

我正在学习Kotlin,具有C ++和Java背景。我希望以下内容可以打印true,而不是false。我知道==映射到equalsequals的默认实施不会比较每个成员,即firstNamelastName吗?如果是这样,它是否会将字符串值视为相等(因为==再次映射到equal)?显然,有一些与平等和身份有关的事情,我还没有在Kotlin做对。

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

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

3 个答案:

答案 0 :(得分:21)

参考平等

<强>爪哇

在Java中,equals的默认实现会比较变量的reference,这是== 总是的变量:

  

equals的{​​{1}}方法实现了最具辨识力的方法   对象可能的等价关系;也就是说,对于任何非null   引用值x和y,当且仅当x 时,此方法返回Object   和y引用同一个对象true的值为x == y)。

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

<强>科特林

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

结构平等

每当我们想要结构而不是引用相等时,我们可以覆盖==,默认情况下从不完成<正如您所建议的那样,正常类。在Kotlin中,我们可以使用equals,编译器会根据构造函数属性自动创建一个实现(读取here)。

如果您覆盖data class(反之亦然)手动,请务必覆盖hashCode,并坚持使用两种方法中非常严格的contracts。 Kotlin的编译器生成的实现确实满足了合同。

答案 1 :(得分:6)

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

答案 2 :(得分:2)

  

== for equality

     

在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"
}

在您的情况下,MyPerson用于data class自动生成通用方法的实现(toStringequalshashCode)。