Kotlin 中的平等
Equality in Kotlin
我正在学习 Kotlin,具有 C++ 和 Java 背景。我期待以下打印 true
,而不是 false
。我知道 ==
映射到 equals
。 equals
的默认实现是否不比较每个成员,即 firstName
和 lastName
?如果是这样,它不会将字符串值视为相等(因为 ==
再次映射到 equals
)吗?显然,我在 Kotlin 中还没有正确理解与平等与身份相关的内容。
class MyPerson(val firstName: String, val lastName: String)
fun main(args: Array<String>) {
println(MyPerson("Charlie", "Parker") == MyPerson("Charlie", "Parker"))
}
您描述的默认 equals
实现仅适用于数据 类。不适用于从 Any
继承实现的常规 类,只需使对象等于自身即可。
引用平等
Java
在Java中,equals
的默认实现比较变量的reference,这就是==
always所做的:
The equals
method for class Object
implements the most discriminating
possible equivalence relation on objects; that is, for any non-null
reference values x and y, this method returns true
if and only if x
and y refer to the same object (x == y
has the value true
).
我们称之为“参考平等”。
Kotlin
在 Kotlin 中 ==
被编译为 equals
,而 ===
相当于 Java 的 ==
.
结构平等
每当我们想要结构而不是引用平等时,我们可以覆盖equals
,即按照您的建议,normal 类 默认情况下从不 完成。在 Kotlin 中,我们可以使用 data class
,编译器会根据构造函数属性自动为其创建一个实现(阅读 here)。
如果您手动覆盖 equals
(反之亦然),请记住始终覆盖 hashCode
并坚持非常严格的 contracts两种方法。 Kotlin 的编译器生成的实现确实满足契约。
== for equality
In Java, you can use == to compare primitive and reference types. If applied to primitive types, Java’s == compares values, whereas == on reference types compares references. Thus, in Java, there’s the well-known practice of always calling equals, and there’s the well-known problem of forgetting to do so.
In Kotlin, == is the default way to compare two objects: it compares their values by calling equals under the hood. Thus, if equals is overridden in your class, you can safely compare its instances using ==. For reference comparison, you can use the === operator, which works exactly the same as == in 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
,它自动生成通用方法(toString
、equals
和 hashCode
)的实现。
我正在学习 Kotlin,具有 C++ 和 Java 背景。我期待以下打印 true
,而不是 false
。我知道 ==
映射到 equals
。 equals
的默认实现是否不比较每个成员,即 firstName
和 lastName
?如果是这样,它不会将字符串值视为相等(因为 ==
再次映射到 equals
)吗?显然,我在 Kotlin 中还没有正确理解与平等与身份相关的内容。
class MyPerson(val firstName: String, val lastName: String)
fun main(args: Array<String>) {
println(MyPerson("Charlie", "Parker") == MyPerson("Charlie", "Parker"))
}
您描述的默认 equals
实现仅适用于数据 类。不适用于从 Any
继承实现的常规 类,只需使对象等于自身即可。
引用平等
Java
在Java中,equals
的默认实现比较变量的reference,这就是==
always所做的:
The
equals
method for classObject
implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returnstrue
if and only if x and y refer to the same object (x == y
has the valuetrue
).
我们称之为“参考平等”。
Kotlin
在 Kotlin 中 ==
被编译为 equals
,而 ===
相当于 Java 的 ==
.
结构平等
每当我们想要结构而不是引用平等时,我们可以覆盖equals
,即按照您的建议,normal 类 默认情况下从不 完成。在 Kotlin 中,我们可以使用 data class
,编译器会根据构造函数属性自动为其创建一个实现(阅读 here)。
如果您手动覆盖 equals
(反之亦然),请记住始终覆盖 hashCode
并坚持非常严格的 contracts两种方法。 Kotlin 的编译器生成的实现确实满足契约。
== for equality
In Java, you can use == to compare primitive and reference types. If applied to primitive types, Java’s == compares values, whereas == on reference types compares references. Thus, in Java, there’s the well-known practice of always calling equals, and there’s the well-known problem of forgetting to do so.
In Kotlin, == is the default way to compare two objects: it compares their values by calling equals under the hood. Thus, if equals is overridden in your class, you can safely compare its instances using ==. For reference comparison, you can use the === operator, which works exactly the same as == in 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
,它自动生成通用方法(toString
、equals
和 hashCode
)的实现。