69

我有以下数据类

data class PuzzleBoard(val board: IntArray) {
    val dimension by lazy { Math.sqrt(board.size.toDouble()).toInt() }
}

equals()我免费阅读了 Kotlin get /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))

但是,以下语句仍然返回错误。

board1 == board2
board1.equals(board2)
4

4 回答 4

101

在 Kotlindata类的相等性检查中,数组,就像其他类一样,使用equals(...)比较,它比较数组引用,而不是内容。此处描述了此行为:

所以,每当你说

  • arr1 == arr2

  • DataClass(arr1) == DataClass(arr2)

  • ...

你得到的数组比较通过equals(),即参考。

鉴于,

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


要覆盖它并在结构上比较数组,您可以在数据类中使用and实现equals(...)+ :hashCode()Arrays.equals(...)Arrays.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 可以为非数据类自动生成的。

另一种解决方案是使用List<Int>而不是IntArray. 列表在结构上进行比较,因此您无需覆盖任何内容。

于 2016-05-30T11:28:43.350 回答
7

在 Kotlin 中,和equals()之间的行为不同,如下面的代码所示:ListArray

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().

来源:Array.contentEquals() 文档List.equals() 文档

于 2019-10-11T16:44:19.333 回答
7

对于Kotlin 中的Data 类,如果两个对象的参数值相同,则 hashcode() 方法将生成并返回相同的整数。

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()))

运行此代码将返回TrueFalse,因为当我们创建secondUser对象时,我们传递了与对象user相同的参数,因此为它们生成的 hashCode() 整数将相同。

如果你要检查这个:

println(user.equals(thirdUser))

它将返回错误。

根据 hashCode() 方法文档

open fun hashCode(): Int (source)

返回对象的哈希码值。hashCode 的一般合约是:

每当在同一个对象上多次调用它时,hashCode 方法必须始终返回相同的整数,前提是没有修改对象上相等比较中使用的信息。

如果两个对象根据 equals() 方法相等,则对两个对象中的每一个调用 hashCode 方法必须产生相同的整数结果。

有关更多详细信息,请参见此处的讨论

于 2017-06-07T07:09:35.130 回答
6

Kotlin 实现:

override fun equals(other: Any?): Boolean {
    when (other) {
        is User -> {
            return this.userId == other.userId &&
                    this.userName == other.userName
        }
        else -> return false
    }
}
于 2021-03-02T09:50:15.877 回答