5

I've started using Kotlin as a substitute for java and quite like it. However, I've been unable to find a solution to this without jumping back into java-land:

I have an Iterable<SomeObject> and need to convert it to a list so I can iterate through it more than once. This is an obvious application of an immutable list, as all I need to do is read it several times. How do I actually put that data in the list at the beginning though? (I know it's an interface, but I've been unable to find an implementation of it in documentation)

Possible (if unsatisfactory) solutions:

val valueList = arrayListOf(values)
// iterate through valuelist

or

fun copyIterableToList(values: Iterable<SomeObject>) : List<SomeObject> {
    var outList = ArrayList<SomeObject>()
    for (value in values) {
        outList.add(value)
    }
    return outList
}

Unless I'm misunderstanding, these end up with MutableLists, which works but feels like a workaround. Is there a similar immutableListOf(Iterable<SomeObject>) method that will instantiate an immutable list object?

Ruslan
  • 14,229
  • 8
  • 49
  • 67
alhart
  • 113
  • 2
  • 9
  • 1
    Please scan the Kotlin stdlib reference for collections and the different collection types, to become aware of many other functions similar to `toList()` https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections – Jayson Minard Jan 13 '16 at 17:03
  • See also http://stackoverflow.com/questions/33727657/kotlin-and-immutable-collections – mfulton26 Jan 13 '16 at 22:57

1 Answers1

13

In Kotlin, List<T> is a read-only list interface, it has no functions for changing the content, unlike MutableList<T>.

In general, List<T> implementation may be a mutable list (e.g. ArrayList<T>), but if you pass it as a List<T>, no mutating functions will be exposed without casting. Such a list reference is called read-only, stating that the list is not meant to be changed. This is immutability through interfaces which was chosen as the approach to immutability for Kotlin stdlib.

Closer to the question, toList() extension function for Iterable<T> in stdlib will fit: it returns read-only List<T>.

Example:

val iterable: Iterable<Int> = listOf(1, 2, 3)
val list: List<Int> = iterable.toList()
hotkey
  • 140,743
  • 39
  • 371
  • 326
  • 2
    Note that read-only lists work great for instantiating effectively immutable lists but do not work for data classes or other cases where you want to receive a reference to an immutable list because a `MutableList` is a `List` so if a constructor, function, etc. asks for a `List` someone can still pass in a `MutableList` and later modify it. See http://stackoverflow.com/questions/33727657/kotlin-and-immutable-collections/34027828#34027828 for some an example with further details. – mfulton26 Jan 13 '16 at 23:00