Kotlin's List missing "add", "remove", Map missing "put", etc?

CollectionsKotlin

Collections Problem Overview


In Java we could do the following

public class TempClass {
    List<Integer> myList = null;
    void doSomething() {
        myList = new ArrayList<>();
        myList.add(10);
        myList.remove(10);
    }
}

But if we rewrite it to Kotlin directly as below

class TempClass {
    var myList: List<Int>? = null
    fun doSomething() {
        myList = ArrayList<Int>()
        myList!!.add(10)
        myList!!.remove(10)
    }
}

I got the error of not finding add and remove function from my List

I work around casting it to ArrayList, but that is odd needing to cast it, while in Java casting is not required. And that defeats the purpose of having the abstract class List

class TempClass {
    var myList: List<Int>? = null
    fun doSomething() {
        myList = ArrayList<Int>()
        (myList!! as ArrayList).add(10)
        (myList!! as ArrayList).remove(10)
    }
}

Is there a way for me to use List but not needing to cast it, like what could be done in Java?

Collections Solutions


Solution 1 - Collections

> Unlike many languages, Kotlin distinguishes between mutable and immutable collections (lists, sets, maps, etc). Precise control over exactly when collections can be edited is useful for eliminating bugs, and for designing good APIs.

https://kotlinlang.org/docs/reference/collections.html

You'll need to use a MutableList list.

class TempClass {
    var myList: MutableList<Int> = mutableListOf<Int>()
    fun doSomething() {
        // myList = ArrayList<Int>() // initializer is redundant
        myList.add(10)
        myList.remove(10)
    }
}

MutableList<Int> = arrayListOf() should also work.

Solution 2 - Collections

Defining a List collection in Kotlin in different ways:

  • Immutable variable with immutable (read only) list:

     val users: List<User> = listOf( User("Tom", 32), User("John", 64) )
    


  • Immutable variable with mutable list:

     val users: MutableList<User> = mutableListOf( User("Tom", 32), User("John", 64) )
    

or without initial value - empty list and without explicit variable type:

    val users = mutableListOf<User>()
    //or
    val users = ArrayList<User>()
  • you can add items to list:
    • users.add(anohterUser) or
    • users += anotherUser (under the hood it's users.add(anohterUser))


  • Mutable variable with immutable list:

     var users: List<User> = listOf( User("Tom", 32), User("John", 64) )
    

or without initial value - empty list and without explicit variable type:

    var users = emptyList<User>()
  • NOTE: you can add* items to list:
    • users += anotherUser - *it creates new ArrayList and assigns it to users


  • Mutable variable with mutable list:

     var users: MutableList<User> = mutableListOf( User("Tom", 32), User("John", 64) )
    

or without initial value - empty list and without explicit variable type:

    var users = emptyList<User>().toMutableList()
    //or
    var users = ArrayList<User>()
  • NOTE: you can add items to list:
    • users.add(anohterUser)
    • but not using users += anotherUser > Error: Kotlin: Assignment operators ambiguity:
      public operator fun Collection.plus(element: String): List defined in kotlin.collections
      > @InlineOnly public inline operator fun MutableCollection.plusAssign(element: String): Unit defined in kotlin.collections


see also: https://kotlinlang.org/docs/reference/collections.html

Solution 3 - Collections

Agree with all above answers of using MutableList but you can also add/remove from List and get a new list as below.

val newListWithElement = existingList + listOf(element)
val newListMinusElement = existingList - listOf(element)

Or

val newListWithElement = existingList.plus(element)
val newListMinusElement = existingList.minus(element)

Solution 4 - Collections

Apparently, the default List of Kotlin is immutable. To have a List that could change, one should use MutableList as below

class TempClass {
    var myList: MutableList<Int>? = null
    fun doSomething() {
        myList = ArrayList<Int>()
        myList!!.add(10)
        myList!!.remove(10)
    }
}

Updated Nonetheless, it is not recommended to use MutableList unless for a list that you really want to change. Refers to https://hackernoon.com/read-only-collection-in-kotlin-leads-to-better-coding-40cdfa4c6359 for how Read-only collection provides better coding.

Solution 5 - Collections

In Kotlin you must use MutableList or ArrayList.

>Let's see how the methods of MutableList work:

var listNumbers: MutableList<Int> = mutableListOf(10, 15, 20)
// Result: 10, 15, 20

listNumbers.add(1000)
// Result: 10, 15, 20, 1000

listNumbers.add(1, 250)
// Result: 10, 250, 15, 20, 1000

listNumbers.removeAt(0)
// Result: 250, 15, 20, 1000

listNumbers.remove(20)
// Result: 250, 15, 1000

for (i in listNumbers) { 
    println(i) 
}

>Let's see how the methods of ArrayList work:

var arrayNumbers: ArrayList<Int> = arrayListOf(1, 2, 3, 4, 5)
// Result: 1, 2, 3, 4, 5

arrayNumbers.add(20)
// Result: 1, 2, 3, 4, 5, 20

arrayNumbers.remove(1)
// Result: 2, 3, 4, 5, 20

arrayNumbers.clear()
// Result: Empty

for (j in arrayNumbers) { 
    println(j) 
}

Solution 6 - Collections

UPDATE: As of Kotlin 1.3.70, the exact buildList function below is available in the standard library as an experimental function, along with its analogues buildSet and buildMap. See https://blog.jetbrains.com/kotlin/2020/03/kotlin-1-3-70-released/.

Confining Mutability to Builders

The top answers here correctly speak to the difference in Kotlin between read-only List (NOTE: it's read-only, not "immutable"), and MutableList.

In general, one should strive to use read-only lists, however, mutability is still often useful at construction time, especially when dealing with third-party libraries with non-functional interfaces. For cases in which alternate construction techniques are not available, such as using listOf directly, or applying a functional construct like fold or reduce, a simple "builder function" construct like the following nicely produces a read-only list from a temporary mutable one:

val readonlyList = mutableListOf<...>().apply {
  // manipulate your list here using whatever logic you need
  // the `apply` function sets `this` to the `MutableList`
  add(foo1)
  addAll(foos)
  // etc.
}.toList()

and this can be nicely encapsulated into a re-usable inline utility function:

inline fun <T> buildList(block: MutableList<T>.() -> Unit) = 
  mutableListOf<T>().apply(block).toList()

which can be called like this:

val readonlyList = buildList<String> {
  add("foo")
  add("bar")
}

Now, all of the mutability is isolated to one block scope used for construction of the read-only list, and the rest of your code uses the read-only list that is output from the builder.

Solution 7 - Collections

You can do with create new one like this.

var list1 = ArrayList<Int>()
var list2  = list1.toMutableList()
list2.add(item)

Now you can use list2, Thank you.

Solution 8 - Collections

https://kotlinlang.org/docs/reference/collections.html

According to above link List<E> is immutable in Kotlin. However this would work:

var list2 = ArrayList<String>()
list2.removeAt(1)

Solution 9 - Collections

A list is immutable by Default, you can use ArrayList instead. like this :

 val orders = arrayListOf<String>()

then you can add/delete items from this like below:

orders.add("Item 1")
orders.add("Item 2")

> by default ArrayList is mutable so you can perform the operations on it.

Solution 10 - Collections

In concept of immutable data, maybe this is a better way:

class TempClass {
    val list: List<Int> by lazy {
        listOf<Int>()
    }
    fun doSomething() {
        list += 10
        list -= 10
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionElyeView Question on Stackoverflow
Solution 1 - CollectionsfulvioView Answer on Stackoverflow
Solution 2 - CollectionsLukas M.View Answer on Stackoverflow
Solution 3 - Collectionsdinesh salveView Answer on Stackoverflow
Solution 4 - CollectionsElyeView Answer on Stackoverflow
Solution 5 - CollectionsAndy JazzView Answer on Stackoverflow
Solution 6 - CollectionsRamanView Answer on Stackoverflow
Solution 7 - CollectionsDalvinder SinghView Answer on Stackoverflow
Solution 8 - CollectionssgroverView Answer on Stackoverflow
Solution 9 - CollectionsSachinView Answer on Stackoverflow
Solution 10 - CollectionsbbsimonView Answer on Stackoverflow