LivBanana
LivBanana

Reputation: 381

Is there a way to make this Kotlin code more clean?

I have the following code but I am convinced that it could be simpler/more elegant

package org.example

import javax.enterprise.context.ApplicationScoped

@ApplicationScoped
object CanceledRequestsHandler {
  var identifiers = setOf<String>()

  fun add(id: String){
    var mutableIdentifiers = identifiers.toMutableList()
    mutableIdentifiers.add(id)
    this.ids = mutableIds.toSet()
  }
}

I wanted to limit the mutability. Any suggestions t improve my code?

Upvotes: 1

Views: 174

Answers (2)

David P. Caldwell
David P. Caldwell

Reputation: 3831

There is a more elegant way! Try this script file (.kts) with kotlinc (or you can run it within IDEA):

object CanceledRequestsHandler {
  var ids = setOf<String>()

  override fun toString(): String = ids.toString()

  fun add(id: String){
    ids = ids + id
  }
}

System.err.println(CanceledRequestsHandler);
CanceledRequestsHandler.add("foo");
CanceledRequestsHandler.add("bar");
System.err.println(CanceledRequestsHandler);

A bit of explanation:

As a commenter and the accepted answer point out, there's more you can do. If you're trying to limit mutability entirely to add(), you can lock this down further, with something like this:

object CanceledRequestsHandler {
  private var _ids = mutableSetOf<String>()

  val ids
    get() = _ids.toSet()

  override fun toString(): String = ids.toString()

  fun add(id: String) {
    _ids.add(id)
  }
}

System.err.println(CanceledRequestsHandler);
CanceledRequestsHandler.add("foo");
CanceledRequestsHandler.add("bar");
System.err.println(CanceledRequestsHandler);
// Below line does not compile
// CanceledRequestsHandler.ids.add("baz")

Now the only way the ids property can change is via the add() method.

Upvotes: 3

I wanted to limit the mutability

Converting immutable collection to mutable on each data mutation is not a limitation of mutablility, it's just overhead. The worst here is that property is declared as mutable (var). This design may lead to data loss in multi-thread case.

If data mutation is unavoidable, then it's better to have mutable (concurrent in multi-thread case) data collection with immutable property (val).

Even better way to limit mutability will be using a mutable data structure only for a short initialization period, and then freezing it into immutable (see buildSet), but I'm not sure that this approach is applicable in your case.

Upvotes: 1

Related Questions