Equality evaluation in Kotlin

Last Updated : 14 Jun, 2025

Kotlin provides a more expressive and precise way to compare instances by supporting two types of equality checks:

  1. Structural Equality
  2. 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
Comment
Article Tags:

Explore