Equality
In Kotlin, there are two types of equality:
Structural equality (
==) - a check for theequals()functionReferential equality (
===) - a check for two references pointing to the same object
Structural equality
Structural equality verifies if two objects have the same content or structure.
Structural equality is checked by the == operation and its negated counterpart !=.
By convention, an expression like a == b is translated to:
If a is not null, it calls the equals(Any?) function. Otherwise (a is null), it checks that b is referentially equal to null:
Note that there's no point in optimizing your code when comparing to null explicitly: a == null will be automatically translated to a === null.
n Kotlin, the equals() function is inherited by all classes from the Any class. By default, the equals() function implements referential equality.
However, classes in Kotlin can override the equals() function to provide a custom equality logic and, in this way, implement structural equality.
Value classes and data classes are two specific Kotlin types that automatically override the equals() function. That's why they implement structural equality by default.
However, in the case of data classes, if the equals() function is marked as final in the parent class, its behaviour remains unchanged (behaviour of parent class will be used) .
Distinctly, non-data classes (those not declared with the data modifier) do not override the equals() function by default. Instead, non-data classes implement referential equality behavior inherited from the Any class.
To implement structural equality, non-data classes require a custom equality logic to override the equals() function.
To provide a custom equals check implementation, override the equals(other: Any?): Boolean function:
Functions with the same name and other signatures (like equals(other: Foo)) don't affect equality checks with the operators == and !=.
Structural equality has nothing to do with comparison defined by the Comparable<...> interface, so only a custom equals(Any?) implementation may affect the behavior of the operator.
Referential equality
Referential equality verifies the memory addresses of two objects to determine if they are the same instance.
Referential equality is checked by the === operation and its negated counterpart !==.
a === b evaluates to true if and only if a and b point to the same object:
For values represented by primitive types at runtime (for example, Int), the === equality check is equivalent to the == check.
Array equality
To compare whether two arrays have the same elements in the same order, use contentEquals().