Kotlin 中数据 class 的等于方法
Equals method for data class in Kotlin
我有以下数据class
data class PuzzleBoard(val board: IntArray) {
val dimension by lazy { Math.sqrt(board.size.toDouble()).toInt() }
}
我阅读了 Kotlin 中的数据 classes 免费获取 equals()
/hashcode()
方法。
我实例化了两个对象。
val board1 = PuzzleBoard(intArrayOf(1,2,3,4,5,6,7,8,0))
val board2 = PuzzleBoard(intArrayOf(1,2,3,4,5,6,7,8,0))
但是,下面的陈述return仍然是错误的。
board1 == board2
board1.equals(board2)
在 Kotlin data
classes 中,数组与其他 classes 一样,使用 equals(...)
进行比较,它比较数组引用,而不是内容。此行为描述为 here:
So, whenever you say
arr1 == arr2
DataClass(arr1) == DataClass(arr2)
- ...
you get the arrays compared through equals()
, i.e. referentially.
鉴于此,
val arr1 = intArrayOf(1, 2, 3)
val arr2 = intArrayOf(1, 2, 3)
println(arr1 == arr2) // false is expected here
println(PuzzleBoard(arr1) == PuzzleBoard(arr2)) // false too
要覆盖它并在结构上比较数组,您可以在数据 class 中使用 Arrays.equals(...)
and Arrays.hashCode(...)
: 实现 equals(...)
+hashCode()
override fun equals(other: Any?): Boolean{
if (this === other) return true
if (other?.javaClass != javaClass) return false
other as PuzzleBoard
if (!Arrays.equals(board, other.board)) return false
return true
}
override fun hashCode(): Int{
return Arrays.hashCode(board)
}
这段代码是IntelliJ IDEA针对非数据自动生成的classes.
另一个解决方案是使用 List<Int>
而不是 IntArray
。列表在结构上进行比较,因此您不需要覆盖任何内容。
对于 Kotlin 中的 Data classes,如果两个对象的参数值相同,hashcode() 方法将生成和 return 相同的整数。
val user = User("Alex", 1)
val secondUser = User("Alex", 1)
val thirdUser = User("Max", 2)
println(user.hashCode().equals(secondUser.hashCode()))
println(user.hashCode().equals(thirdUser.hashCode()))
运行 此代码将 return True 和 False 与我们创建 时一样secondUser 对象我们传递了与对象 user 相同的参数,因此为它们生成的 hashCode() 整数将相同。
另外,如果你要检查这个:
println(user.equals(thirdUser))
它会 return 错误。
根据 hashCode() 方法文档
open fun hashCode(): Int (source)
Returns a hash code value for the object. The general contract of
hashCode is:
Whenever it is invoked on the same object more than once, the hashCode
method must consistently return the same integer, provided no
information used in equals comparisons on the object is modified.
If two objects are equal according to the equals() method, then calling
the hashCode method on each of the two objects must produce the same
integer result.
有关详细信息,请参阅此讨论 here
在 Kotlin 中,equals()
在 List
和 Array
之间的行为不同,您可以从下面的代码中看到:
val list1 = listOf(1, 2, 3)
val list2 = listOf(1, 2, 3)
val array1 = arrayOf(1, 2, 3)
val array2 = arrayOf(1, 2, 3)
//Side note: using a==b is the same as a.equals(b)
val areListsEqual = list1 == list2// true
val areArraysEqual = array1 == array2// false
List.equals()
检查两个列表是否具有相同的大小并且包含相同顺序的相同元素。
Array.equals()
只是进行实例引用检查。由于我们创建了两个数组,它们指向内存中的不同对象,因此不被认为是相等的。
从 Kotlin 1.1 开始,要实现与 List
相同的行为,您可以使用 Array.contentEquals()
.
Kotlin 实现:
override fun equals(other: Any?): Boolean {
when (other) {
is User -> {
return this.userId == other.userId &&
this.userName == other.userName
}
else -> return false
}
}
我有以下数据class
data class PuzzleBoard(val board: IntArray) {
val dimension by lazy { Math.sqrt(board.size.toDouble()).toInt() }
}
我阅读了 Kotlin 中的数据 classes 免费获取 equals()
/hashcode()
方法。
我实例化了两个对象。
val board1 = PuzzleBoard(intArrayOf(1,2,3,4,5,6,7,8,0))
val board2 = PuzzleBoard(intArrayOf(1,2,3,4,5,6,7,8,0))
但是,下面的陈述return仍然是错误的。
board1 == board2
board1.equals(board2)
在 Kotlin data
classes 中,数组与其他 classes 一样,使用 equals(...)
进行比较,它比较数组引用,而不是内容。此行为描述为 here:
So, whenever you say
arr1 == arr2
DataClass(arr1) == DataClass(arr2)
- ...
you get the arrays compared through
equals()
, i.e. referentially.
鉴于此,
val arr1 = intArrayOf(1, 2, 3)
val arr2 = intArrayOf(1, 2, 3)
println(arr1 == arr2) // false is expected here
println(PuzzleBoard(arr1) == PuzzleBoard(arr2)) // false too
要覆盖它并在结构上比较数组,您可以在数据 class 中使用
Arrays.equals(...)
and Arrays.hashCode(...)
: 实现 equals(...)
+hashCode()
override fun equals(other: Any?): Boolean{
if (this === other) return true
if (other?.javaClass != javaClass) return false
other as PuzzleBoard
if (!Arrays.equals(board, other.board)) return false
return true
}
override fun hashCode(): Int{
return Arrays.hashCode(board)
}
这段代码是IntelliJ IDEA针对非数据自动生成的classes.
另一个解决方案是使用 List<Int>
而不是 IntArray
。列表在结构上进行比较,因此您不需要覆盖任何内容。
对于 Kotlin 中的 Data classes,如果两个对象的参数值相同,hashcode() 方法将生成和 return 相同的整数。
val user = User("Alex", 1)
val secondUser = User("Alex", 1)
val thirdUser = User("Max", 2)
println(user.hashCode().equals(secondUser.hashCode()))
println(user.hashCode().equals(thirdUser.hashCode()))
运行 此代码将 return True 和 False 与我们创建 时一样secondUser 对象我们传递了与对象 user 相同的参数,因此为它们生成的 hashCode() 整数将相同。
另外,如果你要检查这个:
println(user.equals(thirdUser))
它会 return 错误。
根据 hashCode() 方法文档
open fun hashCode(): Int (source)
Returns a hash code value for the object. The general contract of hashCode is:
Whenever it is invoked on the same object more than once, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified.
If two objects are equal according to the equals() method, then calling the hashCode method on each of the two objects must produce the same integer result.
有关详细信息,请参阅此讨论 here
在 Kotlin 中,equals()
在 List
和 Array
之间的行为不同,您可以从下面的代码中看到:
val list1 = listOf(1, 2, 3)
val list2 = listOf(1, 2, 3)
val array1 = arrayOf(1, 2, 3)
val array2 = arrayOf(1, 2, 3)
//Side note: using a==b is the same as a.equals(b)
val areListsEqual = list1 == list2// true
val areArraysEqual = array1 == array2// false
List.equals()
检查两个列表是否具有相同的大小并且包含相同顺序的相同元素。
Array.equals()
只是进行实例引用检查。由于我们创建了两个数组,它们指向内存中的不同对象,因此不被认为是相等的。
从 Kotlin 1.1 开始,要实现与 List
相同的行为,您可以使用 Array.contentEquals()
.
Kotlin 实现:
override fun equals(other: Any?): Boolean {
when (other) {
is User -> {
return this.userId == other.userId &&
this.userName == other.userName
}
else -> return false
}
}