Structural vs Referential Equality in Kotlin: Key Differences Explained
structural equality (checked with ==) compares the content or data inside objects, while referential equality (checked with ===) checks if two references point to the exact same object in memory. Use == to compare values and === to compare object identities.Quick Comparison
Here is a quick table to compare structural and referential equality in Kotlin.
| Aspect | Structural Equality (==) | Referential Equality (===) |
|---|---|---|
| What it compares | Content or data inside objects | Memory address or object identity |
| Operator used | == | === |
| Checks | If objects have equal values | If both references point to the same object |
| Null safety | Handles nulls safely | Also handles nulls but checks reference |
| Default behavior | Calls equals() method | Checks reference directly |
| Typical use case | Comparing data equality | Checking if two variables refer to the same instance |
Key Differences
Structural equality in Kotlin is about comparing the actual content or data inside two objects. When you use ==, Kotlin internally calls the equals() method of the objects. This means two different objects with the same data are considered equal.
On the other hand, referential equality checks if two variables point to the exact same object in memory. Using === compares the references themselves, not the content. Even if two objects have the same data, if they are different instances, === returns false.
In summary, use == when you want to check if two objects are logically equal by their data, and use === when you want to know if two references are literally the same object.
Code Comparison
data class Person(val name: String, val age: Int) fun main() { val person1 = Person("Alice", 30) val person2 = Person("Alice", 30) val person3 = person1 println(person1 == person2) // Structural equality println(person1 === person2) // Referential equality println(person1 === person3) // Referential equality }
Referential Equality Equivalent
fun main() {
val a = "hello"
val b = "hello"
val c = a
println(a == b) // Structural equality
println(a === b) // Referential equality
println(a === c) // Referential equality
}When to Use Which
Choose structural equality (==) when you want to compare the actual data or content of objects, such as checking if two strings or data class instances hold the same values.
Choose referential equality (===) when you need to know if two variables point to the exact same object in memory, which is useful for identity checks or performance optimizations.
In most everyday Kotlin programming, == is the preferred choice for equality checks because it focuses on meaningful data comparison.
Key Takeaways
== for comparing object content (structural equality).=== for checking if two references point to the same object (referential equality).== calls the equals() method internally.=== compares memory addresses directly.== for most equality checks in Kotlin.