我在kotlin中搜索equals/hashcode
我了解等于和 (==) 在数据类中工作正常,但对于常规类,我想我们应该覆盖等于和哈希码方法:
class GroupWithData {
var group: Group? = null
var data: List<Data>? = null
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as GroupWithData
if (group!= other.group) return false
if (data!= other.data) return false
return true
}
override fun hashCode(): Int {
var result = group?.hashCode() ?: 0
result = 31 * result + (data?.hashCode() ?: 0)
return result
}
但是当我尝试等于两个列表时,它不起作用。
PS:组和数据类是“数据类”
检查data class Data
的内容:它是否覆盖equals
?Data
类的任何成员是否属于非原始类型并覆盖equals
?有关更多解释和示例,请进一步阅读。
你完全正确,对于常规类,如果我们想通过值而不是引用来比较两个对象,我们必须重写< code>equals和< code>hashCode函数。< code>equals的实现可以是您喜欢的任何东西。这完全取决于您的应用程序的业务逻辑,以及在您的特定情况下什么被认为是“相等”的。
您拥有的实现实际上已经足够好了。基本上检查身份(也称为通过引用进行比较,< code>=== Kotlin操作符),检查< code>other是否属于同一个实例类,任何进一步的工作都取决于业务逻辑。
hashCode
函数的实现可能使用您在equals
函数中比较过的相同成员,但使用类的其他成员也可以。
注意:通常认为最好的做法是覆盖函数等于
和哈希代码
。即使哈希代码不直接在您的代码
中使用,它也可以在您可以使用的库的某些实现下使用。如果两个对象相等,则它们的哈希代码也必须相等。如果对象未更改,哈希代码必须保持不变。
我不太确定,但问题可能出在Data
数据类或其成员的值中。
我用基元类型和<code>数据类data</code>运行了两个简单的测试,看起来如下:
测试#1
var list1: List<Int> = listOf(1,2,3,4)
var list2: List<Int> = arrayListOf(1,2,3,4)
var list3: List<Int> = LinkedList<Int>().also { it.addAll(listOf(1,2,3,4)) }
fun equals(): Boolean {
return list1 == list3 && list1 == list2 && list2 == list3
}
println(equals())
测试#2
data class Data(var i: Int = 0)
var list1: List<Data> = listOf(Data(1),Data(2),Data(3),Data(4))
var list2: List<Data> = arrayListOf(Data(1),Data(2),Data(3),Data(4))
var list3: List<Data> = LinkedList<Data>().also { it.addAll(listOf(Data(1),Data(2),Data(3),Data(4))) }
fun equals(): Boolean {
return list1 == list3 && list1 == list2 && list2 == list3
}
println(equals())
在这两种情况下,印刷品都是真实的
。这是真的,因为在 Kotlin 文档之后它说:
如果两个列表在相同的位置具有相同的大小和结构上相等的元素,则它们被认为是相等的。
文件参考。
这里描述了结构上的平等。
现在,这里是修改后的< code>Data类,在它的< code>equals实现中发生了一些奇怪的事情:
data class Data(var i: Int = 0) {
// Custom equals!
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Data
return (i + other.i) % 2 == 1
}
}
如果尝试将相同的列表与按相同顺序添加的Data
对象进行比较,则列表将不相等,因为两个Data\
的比较有时会返回false
。
如果< code>Data类包含另一个非原始类型,并且它的< code>equals方法没有为实际相等的对象返回< code>true,这也可能是问题所在。如此等等。