等于kotlin中数据类的方法

时间:2022-03-07 13:27:51

I have the following data class

我有以下数据类

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

I read that data classes in Kotlin get equals()/hashcode() method for free.

我读到Kotlin中的数据类可以免费获得equals()/ hashcode()方法。

I instantiated two objects.

我实例化了两个对象。

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

But still the following statements return false.

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

board1 == board2
board1.equals(board2)

2 个解决方案

#1


41  

In Kotlin data classes equality check, arrays, just like other classes, are compared using equals(...), which compares the arrays references, not the content. This behavior is described here:

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

So, whenever you say

所以,无论何时你说

  • arr1 == arr2

    arr1 == arr2

  • DataClass(arr1) == DataClass(arr2)

    DataClass(arr1)== DataClass(arr2)

  • ...
  • ...

you get the arrays compared through equals(), i.e. referentially.

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

Given that,

鉴于,

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


To override this and have the arrays compared structurally, you can implement equals(...)+ hashCode() in your data class using Arrays.equals(...) and 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)
}

This code is what IntelliJ IDEA can automatically generate for non-data classes.

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

Another solution is to use List<Int> instead of IntArray. Lists are compared structurally, so that you won't need to override anything.

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

#2


0  

For Data classes in Kotlin, hashcode() method will generate and return the same integer if parameters values are same for both objects.

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

Running this code will return True and False as when we created secondUser object we have passed same argument as object user, so hashCode() integer generated for both of them will be same.

运行此代码将返回True和False,因为当我们创建secondUser对象时,我们已经将相同的参数作为对象用户传递,因此为它们生成的hashCode()整数将是相同的。

also if you will check this:

如果你要检查这个:

println(user.equals(thirdUser))

It will return false.

它将返回false。

As per hashCode() method docs

根据hashCode()方法docs

open fun hashCode(): Int (source)

Returns a hash code value for the object. The general contract of hashCode is:

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

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.

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

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.

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

For more details see this discussion here

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

#1


41  

In Kotlin data classes equality check, arrays, just like other classes, are compared using equals(...), which compares the arrays references, not the content. This behavior is described here:

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

So, whenever you say

所以,无论何时你说

  • arr1 == arr2

    arr1 == arr2

  • DataClass(arr1) == DataClass(arr2)

    DataClass(arr1)== DataClass(arr2)

  • ...
  • ...

you get the arrays compared through equals(), i.e. referentially.

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

Given that,

鉴于,

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


To override this and have the arrays compared structurally, you can implement equals(...)+ hashCode() in your data class using Arrays.equals(...) and 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)
}

This code is what IntelliJ IDEA can automatically generate for non-data classes.

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

Another solution is to use List<Int> instead of IntArray. Lists are compared structurally, so that you won't need to override anything.

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

#2


0  

For Data classes in Kotlin, hashcode() method will generate and return the same integer if parameters values are same for both objects.

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

Running this code will return True and False as when we created secondUser object we have passed same argument as object user, so hashCode() integer generated for both of them will be same.

运行此代码将返回True和False,因为当我们创建secondUser对象时,我们已经将相同的参数作为对象用户传递,因此为它们生成的hashCode()整数将是相同的。

also if you will check this:

如果你要检查这个:

println(user.equals(thirdUser))

It will return false.

它将返回false。

As per hashCode() method docs

根据hashCode()方法docs

open fun hashCode(): Int (source)

Returns a hash code value for the object. The general contract of hashCode is:

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

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.

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

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.

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

For more details see this discussion here

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