Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equals method for data class in Kotlin

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.

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.

board1 == board2 board1.equals(board2) 
like image 422
Vaibhav Avatar asked May 30 '16 11:05

Vaibhav


People also ask

Can data class have methods Kotlin?

Data classes specialize in holding data. The Kotlin compiler automatically generates the following functionality for them: A correct, complete, and readable toString() method. Value equality-based equals() and hashCode() methods.

What is the equals function in Kotlin?

equals(x) returns true. Transitive: for any non-null values x , y , and z , if x. equals(y) returns true and y. equals(z) returns true, then x.

What happens if you explicitly provide equals function to a data class in Kotlin?

If there are explicit implementations of equals() , hashCode() , or toString() in the data class body or final implementations in a superclass, then these functions are not generated, and the existing implementations are used.

What are the types of equality in Kotlin?

In Kotlin there are two types of equality: Structural equality (== - a check for equals ()) Referential equality (=== - two references point to the same object)

How to compare the data of two variables in Kotlin?

We often need to compare the data of two variables or objects or the references of two objects in Kotlin. This brings in another question, which equality check should we use in which case. Let’s figure out what are the types of checks available in Kotlin. Structural Equality (‘==’) ==operator is used to compare the data of two variables.

What does Kotlin mean?

Answer: Kotlin provides a special type of class called data class, which is usually used for objects that act as a store for data properties and has no business logic or member functions. It provides a lot of advantages with reduced boilerplate code.

How to use === operator in Kotlin?

===operator is used to compare the reference of two variable or object. It will only be trueif both the objects or variables pointing to the same object. The negated counterpart of ===in Kotlin is !==which is used to compare if both the values are not equal to each other.


1 Answers

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:

So, whenever you say

  • arr1 == arr2

  • DataClass(arr1) == DataClass(arr2)

  • ...

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

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.

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

like image 85
hotkey Avatar answered Sep 28 '22 09:09

hotkey