如何在kotlin中实现equals/hashcode?
我在kotlin中搜索equals/hashcode时使用堆栈 我理解equals和(=)在数据类中可以很好地工作,但在常规类中,我认为我们应该重写equals和hashcode方法:如何在kotlin中实现equals/hashcode?,kotlin,equals,Kotlin,Equals,我在kotlin中搜索equals/hashcode时使用堆栈 我理解equals和(=)在数据类中可以很好地工作,但在常规类中,我认为我们应该重写equals和hashcode方法: class GroupWithData { var group: Group? = null var data: List<Data>? = null override fun equals(other: Any?): Boolean { if (thi
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
}
class-GroupWithData{
变量组:组?=null
变量数据:列表?=null
覆盖乐趣等于(其他:任何?):布尔值{
如果(this==other)返回true
if(javaClass!=other?.javaClass)返回false
其他as GroupWithData
如果(组!=other.group)返回false
如果(data!=other.data)返回false
返回真值
}
重写哈希代码():Int{
var result=组?.hashCode()?:0
结果=31*result+(数据?.hashCode()?:0)
返回结果
}
但当我试图使两个列表相等时,它并不正确
PS:组和数据类是“数据类”TL;DR检查
数据类数据的内容:它是否覆盖等于?是否数据
类的任何成员都是非原始类型且覆盖等于?更多解释和示例请进一步阅读
如何在kotlin中实现equals/hashcode?
你完全正确,对于常规类,如果我们想通过值而不是引用来比较两个对象,我们必须重写equals
和hashCode
函数。equals
的实现可能是你喜欢的任何东西。这完全取决于应用程序的业务逻辑和定义在您的特殊情况下,请使用“同等”emed
您拥有的实现实际上已经足够好了,可以开始了。基本上检查标识(也称为引用比较,===
Kotlin操作符),检查其他
是否属于同一实例类,进一步的操作取决于业务逻辑
hashCode
函数的实现可能会使用与您在equals
函数中比较过的相同的成员,但是使用类的其他成员也一样好
注意:通常认为好的做法是重写两个函数equals
和hashCode
。即使hashCode
没有直接在代码中使用,它也可以在您可以使用的库的某些实现下使用。如果两个对象相等,它们的哈希代码也必须相等如果对象没有更改,请保持不变
为什么两个列表可能不相等?
我不太确定,但问题可能在于数据
数据类或其成员的值
我使用原语类型和数据类数据运行了两个简单的测试,如下所示:
测试#1
如果尝试将相同的列表与按相同顺序添加的数据
对象进行比较,列表将不相等,因为两个数据
对象的比较有时会返回false
<> > <代码>数据< /代码>类包含另一个非本原类型,它的<代码>等于方法不返回“代码>真/ <代码>对于实际相等的对象,这也可能是问题。等等。如果有不同类型的<代码>列表< /代码>,您会考虑两个<代码> GROPUWS数据< /代码> s是否相等?(例如,<代码> ARAYLIST/<代码>和<代码> LIKEDLIST < /COD>),但以相同的顺序保存相同的元素(是的),我认为这个列表是均等的,通常是代码< >均衡器()/<代码> > <代码>清单>代码> S应该做你想做的事。(假设你没有一些奇怪的实现来破坏它……)数据
绝对是一个数据类
?它有什么属性类型?(如果有的话不是原语或字符串,这些属性可能会比较不相等吗?)我想指出,在调试中,列表1(列表)的每个元素都等于列表2(列表)如果对它们进行迭代,但由于某种原因列表本身不是,现在这对我来说是最不可理解的事情,不知何故,这可能是因为我从Room数据库检索数据?实际的列表类是什么?(list
是一个接口,所以它需要一些类来实现它。它应该实现equals()
来比较内容,或者更可能的是,继承自例如AbstractList
的内容。但如果没有,这将解释您的问题。)
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())
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())
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
}
}