Why Kotlin Data Class Lambdas Break Equality and How to Fix It
This article explains how Kotlin treats lambda expressions as distinct objects, causing two data class instances with identical lambda bodies to be unequal, demonstrates the problem with code examples, and shows how extracting the lambda into a shared reference restores proper equality, highlighting implications for equals, hashCode, and Compose.
Introduction
Kotlin lambda expressions are widely used, but a subtle pitfall exists when they are stored in a data class: each lambda instance is a separate object, breaking the data class's structural equality and potentially causing hidden bugs.
Problem
Consider a simple data class that takes a lambda in its constructor:
data class Action(
val label: String,
val onClick: () -> Unit
)
fun main() {
val action1 = Action("Retry") { println("Retrying…") }
val action2 = Action("Retry") { println("Retrying…") }
println(action1 == action2)
}The output is false. Although the two Action instances have the same label and identical lambda bodies, they are not equal because Kotlin compares lambdas by reference. Each { println("Retrying…") } creates a new object in memory.
Solution
Extract the lambda into a shared variable and pass the same reference to both instances:
val retryLambda: () -> Unit = { println("Retrying…") }
val action1 = Action("Retry", retryLambda)
val action2 = Action("Retry", retryLambda)
println(action1 == action2)The output is true. Both instances now hold the same lambda reference, so the generated equals() method compares the same object.
Equality for data classes is based on the references of lambda properties, not on their functional bodies, which also affects equals(), hashCode(), and caching logic.
Conclusion
This single tip reminds developers that lambda reference equality can break equals() and hashCode() implementations, leading to bugs in caching or interview questions. In Jetpack Compose, lambdas are treated as stable types, so the issue does not cause unnecessary recompositions.
AndroidPub
Senior Android Developer & Interviewer, regularly sharing original tech articles, learning resources, and practical interview guides. Welcome to follow and contribute!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
