Как скопировать список в Котлине?
я использую
val selectedSeries = mutableListOf<String>()
selectedSeries.addAll(series)
Есть способ попроще?
Ответы:
Это прекрасно работает.
val selectedSeries = series.toMutableList()
val selectedSeries = series.toList()также работает, потому что требует toMutableList()своей реализации.
===и должен сказать , toList()не копировать коллекции, но toMutableList()делает
Iterable.toList()возвращается emptyList(), который всегда возвращает один и тот же (неизменяемый) объект. Так что если вы попробуете, emptyList()вы получите тот же объект обратно.
toMutableList()возвращает новый список: «Возвращает новый MutableList, заполненный всеми элементами этой коллекции».
Ты можешь использовать
Список -> 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())
Обновление: с новым механизмом вывода типа (опция в Kotlin 1.3) мы можем опустить параметр общего типа в 1-м примере и получить следующее:
1. val selectedSeries = mutableListOf().apply { addAll(series) }
FYI. Способ включения нового вывода - 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}
Это будет работать для многих типов коллекций.
Maps. Он компилируется, но, поскольку 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)