63 votes

Méthode Equals pour la classe de données dans Kotlin

J'ai la classe de données suivante

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

J'ai lu que les classes de données dans Kotlin obtiennent gratuitement la méthode equals () / hashcode ().

J'ai instancié deux objets.

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

Mais toujours les déclarations suivantes retournent fausses.

 board1 == board2
board1.equals(board2)
 

95voto

hotkey Points 119

Dans Kotlin data classes de contrôle d'égalité, les tableaux, tout comme les autres classes, sont comparées à l'aide d' equals(...), qui compare les tableaux de références, pas le contenu. Ce comportement est décrit ici:

Donc, chaque fois que vous dites

  • arr1 == arr2

  • DataClass(arr1) == DataClass(arr2)

  • ...

vous obtenez les tableaux de comparaison par equals(), c'est à dire referentially.

Étant donné que,

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


Pour remplacer ce et ont les tableaux par rapport structurellement, vous pouvez mettre en oeuvre equals(...)+hashCode() dans votre classe de données à l'aide de Arrays.equals(...) et 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)
}

Ce code est ce que IntelliJ IDEA est possible de générer automatiquement pour les non-classes de données.

Une autre solution est d'utiliser List<Int> au lieu de IntArray. Les listes sont comparés structurellement, de sorte que vous n'aurez pas besoin de modifier quoi que ce soit.

7voto

Tapan parmar Points 876

Pour les classes de Données dans Kotlin, hashcode() la méthode va générer et de revenir par le même entier si les valeurs des paramètres sont les mêmes pour les deux objets.

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

L'exécution de ce code renvoie True et False comme lorsque nous avons créé secondUser objet, nous avons passé même argument que l'objet de l'utilisateur, de sorte hashCode() integer générés pour les deux d'entre eux seront même.

aussi, si vous vérifiez ceci:

println(user.equals(thirdUser))

Elle retourne la valeur false.

Comme par hashCode() la méthode docs

open fun hashCode(): Int (source)

Renvoie un code de hachage de la valeur de l'objet. Les conditions générales du contrat de hashCode est:

Chaque fois qu'elle est invoquée sur le même objet plus d'une fois, le hashCode méthode doit constamment revenir par le même entier, à condition qu'aucun l'information utilisée dans les égaux des comparaisons sur l'objet est modifié.

Si deux objets sont égaux selon la méthode equals (), puis de l'appel d' la méthode hashCode sur chacun des deux objets doivent produire les mêmes résultat sous forme d'entier.

Pour plus de détails, voir cette discussion ici

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X