Kotlin — Copy to Mutate

J Banks
Software Tidbits
Published in
2 min readJun 21, 2020

In this software tidbit, we examine immutability in Kotlin and how to efficiently work with the immutable object when updates are desired. Immutability is provided out of the box with Kotlin. Compared with Java’s options for immutability Kotlin takes much less effort.

A common use case with immutable objects is the need to update a small percentage of the object’s state while ensuring everything else is intact. This usually requires that a new instance is created and all of the immutable state is copied over using a constructor or builder.

With Kotlin’s data classes, a copy function is available to handle this state transfer with ease.

Let’s start with a data class called DataRecord that is used to store three values: firstName, lastName, and zip.

// Immutable data class definition
data class DataRecord(
val firstName: String,
val lastName: String,
val zip: Int)

When creating an instance of the DataRecord, and identifying the instance variables using the val keyword, the access to the three fields are restricted as read-only. To make these mutable, the class would need to declare the instance variables using a var keyword.

Kotlin’s data classes provide a built-in copy function that comes for free. This function assists with transferring the state from one object to another while being able to specify changes.

val originalRecord = DataRecord("Samuel", "Davies", 50322)val updatedRecord = originalRecord.copy(zip = 80322)

Above, the constructor is invoked with the original state of the immutable object. An update is desired and only the zip code field’s value is modified. The change is represented by specifying the new value when invoking the copy function. In this case zip=80322.

DataRecord(firstName=Samuel, lastName=Davies, zip=50322)DataRecord(firstName=Samuel, lastName=Davies, zip=80322)

But wait, what if there is a need to specify more differences than a single field for the new object? In this case, let’s update the firstName and the zip from the original record.

val updatedRecordOfTwoFields = originalRecord.copy(zip=55555,   
firstName="Sammy")

Notice how the order isn’t important as the instance variable name is addressed with its own value. When the object is printed out it results in the the following state.

DataRecord(firstName=Sammy, lastName=Davies, zip=55555)

Now, to double check that the state of the other two objects (original and second object) used in the example are not modified, they are printed out (after the final update) just to be sure!

// Original instance
DataRecord(firstName=Samuel, lastName=Davies, zip=50322)
// First copied instance (Just the zip change)
DataRecord(firstName=Samuel, lastName=Davies, zip=80322)
// Final copied instance (first name change and zip change)
DataRecord(firstName=Sammy, lastName=Davies, zip=55555)

There you have it, immutable objects with Kotlin and the built-in copy function supplied with Kotlin’s data classes. I hope you enjoyed this software tidbit.

Checkout the shared source and don’t forget to like this if you find it useful in your Kotlin development!

Until next time …

--

--