Blog Infos
Author
Published
Topics
, , , ,
Published

In my previous articles, I showed why using var or Array in a Kotlin data class constructor leads to unexpected behavior and subtle bugs.
These issues mostly relate to how equals()hashCode(), and copy() behave under the hood — especially in collections like HashMapHashSet, or in UI frameworks such as Jetpack Compose.

Those problems are related to logic and data modeling, and they often appear when working with collections, comparing objects, or optimizing recompositions.

In this article, we’ll look at another case: using a lambda in the constructor of a data class.

Even if two lambdas do exactly the same thing, they are treated as different objects.
This breaks equality and can lead to subtle bugs when storing or comparing instances.

We’ll look at why this happens, what the implications are, and what to consider if you decide to use this pattern.

Featured On
Comparing data classes with lambdas

Let’s define a simple data class that includes 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)
}

Output:

false

Even though both Action instances have the same label and the same lambda body, they are not considered equal.

This happens because lambdas in Kotlin are compared by reference.
Each { println("Retrying…") } creates a new object in memory — even if the logic is the same.

Reusing the same lambda reference

Now let’s extract the lambda 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)

Output:

true

In this case, both instances receive the same lambda reference, so the equals() function compares the same lambda object — and the result is true.

This demonstrates that equality is based on the lambda’s identity, not on its logic.

Why this detail is worth knowing

To be clear — I haven’t seen this cause real problems in production code.
But I think it’s useful to understand how lambdas behave when used in data class constructors.

If you decide to model your state this way, it’s important to keep in mind that:

  • Lambdas are compared by reference
  • This can break equals() and hashCode()
  • It may lead to subtle issues in lists, caching, or UI state updates

This kind of knowledge is also useful in interviews — especially when you’re asked about how Kotlin handles data classes under the hood.

And if you’ve seen a real-world case where this caused a problem — feel free to share it in the comments.

Job Offers

Job Offers

There are currently no vacancies.

OUR VIDEO RECOMMENDATION

No results found.

Jobs

Conclusion

Lambdas in data class constructors can silently break equality by introducing reference-based comparisons.
It’s a small detail — but one that’s worth understanding.

You might also like:

If you learned something new or found this breakdown useful, feel free to leave a clap — it helps others discover the article.

 

You can also follow me on Medium for more posts about Kotlin, Android development, and practical engineering topics.

Anatolii Frolov
Senior Android Developer
Writing honest, real-world Kotlin & Jetpack Compose insights.
📬 Follow me on Medium

This article was previously published on proandroiddev.com.

Menu