Відповіді:
Це чудово працює.
val selectedSeries = series.toMutableList()
val selectedSeries = series.toList()
також працює, тому що закликає toMutableList()
в його реалізації.
===
і, скажімо toList()
, не копіює колекцію, але toMutableList()
так
Iterable.toList()
повертається emptyList()
, який завжди повертає той самий (незмінний) об'єкт. Тож якщо ви тестуєте, emptyList()
ви отримаєте той самий об’єкт назад.
toMutableList()
повинно повернути новий екземпляр списку, якщо екземпляр, що викликає метод, вже є змінним списком.
Можна використовувати
Список -> toList ()
Масив -> toArray ()
ArrayList -> toArray ()
MutableList -> toMutableList ()
Приклад:
val array = arrayListOf("1", "2", "3", "4")
val arrayCopy = array.toArray() // copy array to other array
Log.i("---> array " , array?.count().toString())
Log.i("---> arrayCopy " , arrayCopy?.count().toString())
array.removeAt(0) // remove first item in array
Log.i("---> array after remove" , array?.count().toString())
Log.i("---> arrayCopy after remove" , arrayCopy?.count().toString())
журнал друку:
array: 4
arrayCopy: 4
array after remove: 3
arrayCopy after remove: 4
Я можу придумати два альтернативних способи:
1. val selectedSeries = mutableListOf<String>().apply { addAll(series) }
2. val selectedSeries = mutableListOf(*series.toTypedArray())
Оновлення: за допомогою нового двигуна Type Inference (включення в Kotlin 1.3) ми можемо опустити параметр загального типу в 1-му прикладі і мати це:
1. val selectedSeries = mutableListOf().apply { addAll(series) }
FYI. Спосіб включення нового Inference - це kotlinc -Xnew-inference ./SourceCode.kt
командний рядок або kotlin { experimental { newInference 'enable'}
Gradle. Щоб отримати докладнішу інформацію про новий тип виводу, перегляньте це відео: KotlinConf 2018 - Новий тип висновку та пов'язані з ним мовні особливості Світлани Ісакової , особливо "висновок для будівельників" у 30 "
Якщо ваш список містить клас даних Kotlin , ви можете це зробити
selectedSeries = ArrayList(series.map { it.copy() })
Ви можете використовувати надане розширення, Iterable.toMutableList()
яке надасть вам новий список. На жаль, його підпис і документація припускають, що це означало , щоб гарантувати , що Iterable
це List
(так само , як toString
і багато інших to<type>
методи). Ніщо не гарантує вам, що це буде новий список. Наприклад, додавання наступного рядка на початку розширення: if (this is List) return this
це законне поліпшення продуктивності (якщо воно справді покращує ефективність).
Крім того, через свою назву отриманий код не дуже зрозумілий.
Я вважаю за краще додати власне розширення, щоб бути впевненим у результаті та створити набагато більш чіткий код (як і у нас для масивів ):
fun <T> List<T>.copyOf(): List<T> {
val original = this
return mutableListOf<T>().apply { addAll(original) }
}
fun <T> List<T>.mutableCopyOf(): MutableList<T> {
val original = this
return mutableListOf<T>().apply { addAll(original) }
}
Зауважте, що addAll
це найшвидший спосіб копіювання, оскільки він використовує нативні System.arraycopy
програми для реалізаціїArrayList
.
Також майте на увазі, що це дасть вам лише дрібну копію .
addAll(this@copyOf)
, бо this
всередині apply
буде посилатися на новостворений порожній список? Або це, або mutableListOf<T>().also { it.addAll(this) }
?
Для дрібної копії пропоную
.map{it}
Це буде працювати для багатьох типів колекцій.
Map
s. Вона компілюється, але оскільки " it
a" Map.Entry
, а копія неглибока, у вас є однакові записи.
Як і в Java:
Список:
val list = mutableListOf("a", "b", "c")
val list2 = ArrayList(list)
Карта:
val map = mutableMapOf("a" to 1, "b" to 2, "c" to 3)
val map2 = HashMap(map)
Якщо припустити, що ви орієнтовані на JVM (або Android); Я не впевнений, що він працює для інших цілей, оскільки він покладається на конструктори копій ArrayList і HashMap.
Я хотів би використовувати в toCollection()
метод розширення :
val original = listOf("A", "B", "C")
val copy = original.toCollection(mutableListOf())
Це створить новий, MutableList
а потім додасть кожен елемент оригіналу до новоствореного списку.
Виведений тут тип буде MutableList<String>
. Якщо ви не хочете викривати змінність цього нового списку, ви можете вказати тип явно як незмінний список:
val copy: List<String> = original.toCollection(mutableListOf())
Для простих списків є багато правильних рішень вище.
Однак це лише для неглибоких списків.
Наведена нижче функція працює для будь-яких двовимірних ArrayList
. ArrayList
на практиці еквівалентний MutableList
. Цікаво, що він не працює при використанні явного MutableList
типу. Якщо вам потрібно більше габаритів, необхідно зробити більше функцій.
fun <T>cloneMatrix(v:ArrayList<ArrayList<T>>):ArrayList<ArrayList<T>>{
var MatrResult = ArrayList<ArrayList<T>>()
for (i in v.indices) MatrResult.add(v[i].clone() as ArrayList<T>)
return MatrResult
}
Демо для цілої матриці:
var mat = arrayListOf(arrayListOf<Int>(1,2),arrayListOf<Int>(3,12))
var mat2 = ArrayList<ArrayList<Int>>()
mat2 = cloneMatrix<Int>(mat)
mat2[1][1]=5
println(mat[1][1])
це показує 12
Ви можете використовувати ArrayList
конструктор:ArrayList(list)