Equality evaluation in Kotlin (original) (raw)
Last Updated : 14 Jun, 2025
Kotlin provides a more expressive and precise way to compare instances by supporting two types of equality checks:
- Structural Equality
- Referential Equality
These two forms of equality help distinguish between value-based and reference-based comparisons, making Kotlin a more robust language compared to many others.
1. Structural Equality (==)
Structural equality is checked through the **== operator and its inverse ****!= operator**. By default, the expression containing **x==y is translated into the call of **equals() function for that type.
From:
x==y
To:
x?.equals(y) ?: (y === null)
This states that,
- If **x is not **null, it calls **x.equals(y).
- If **x is **null, it checks if **y is also **null using referential equality (**===).
This means that **== in Kotlin is **null-safe and doesn't throw a **NullPointerException.
**Note: To use ==, the class should override the equals() method. In Kotlin, data classes automatically generate equals() (and hashCode()) based on their properties.
2. Referential Equality (===)
Referential equality checks whether two variables point to the same object in memory. The === operator is used to determine this:
x === y // true only if x and y refer to the same object instance
The inverse operator !== checks if two references point to different instances. For types that are compiled to primitive types (like Int, Double, etc.), the === and !== operators may behave like == and !=, since primitives don't have object identity in the same way.
Structural vs Referential Equality
**Example:
Kotlin `
data class Square(val side: Int)
fun main() { val square1 = Square(5) val square2 = Square(5) val square3 = square1
// Structural Equality
if (square1 == square2) {
println("Two squares are structurally equal")
} else {
println("Two squares are not structurally equal")
}
// Referential Equality
if (square1 === square2) {
println("Two squares are referentially equal")
} else {
println("Two squares are not referentially equal")
}
// Referential Equality with the same reference
if (square1 === square3) {
println("square1 and square3 refer to the same instance")
}}
`
**Output:
Two squares are structurally equal
Two squares are not referentially equal
square1 and square3 refer to the same instance