等于kotlin中数据类的方法

Vai*_*hav 44 arrays equals kotlin data-class

我有以下数据类

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

我读到Kotlin中的数据类可以免费获得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))
Run Code Online (Sandbox Code Playgroud)

但是仍然以下语句返回false.

board1 == board2
board1.equals(board2)
Run Code Online (Sandbox Code Playgroud)

hot*_*key 71

在Kotlin data类的等式检查中,数组与其他类一样,使用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
Run Code Online (Sandbox Code Playgroud)


要覆盖它并在结构上对数组进行比较,可以使用和在数据类中实现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)
}
Run Code Online (Sandbox Code Playgroud)

此代码是IntelliJ IDEA可以为非数据类自动生成的代码.

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

  • 有关在Kotlin中测试数组值相等性的更多信息,请参见此处:http://stackoverflow.com/q/35272761/1402641 (3认同)
  • 如果你想避免编写自己的equals方法,可以考虑使用`List <Int>`而不是`IntArray`.它不会像内存有效,但除非你创建非常大的数组,否则影响将是名义上的. (2认同)

VIV*_*ARY 10

科特林实现:

override fun equals(other: Any?): Boolean {
    when (other) {
        is User -> {
            return this.userId == other.userId &&
                    this.userName == other.userName
        }
        else -> return false
    }
}
Run Code Online (Sandbox Code Playgroud)


Tap*_*nHP 7

对于Kotlin 中的数据类,如果两个对象的参数值相同,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()))
Run Code Online (Sandbox Code Playgroud)

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

如果你检查这个:

println(user.equals(thirdUser))
Run Code Online (Sandbox Code Playgroud)

它会返回假。

根据 hashCode() 方法文档

open fun hashCode(): Int (source)
Run Code Online (Sandbox Code Playgroud)

返回对象的哈希码值。hashCode 的总合约为:

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

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

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


小智 5

在 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
Run Code Online (Sandbox Code Playgroud)

List.equals() 检查两个列表是否具有相同的大小并以相同的顺序包含相同的元素。

Array.equals()只是做一个实例引用检查。由于我们创建了两个数组,它们指向内存中的不同对象,因此不被认为是相等的。

从 Kotlin 1.1 开始,要实现与 相同的行为List,您可以使用Array.contentEquals().

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