val selectedSeries = series.toList()также работает, потому что требует toMutableList()своей реализации.
Flávio Faria
4
@ FlávioFaria просто протестировали его с ===и должен сказать , toList()не копировать коллекции, но toMutableList()делает
Peppermint Пэдди
3
@PeppermintPaddy Это делает копию, за исключением случая пустых списков. Если источник пуст, Iterable.toList()возвращается emptyList(), который всегда возвращает один и тот же (неизменяемый) объект. Так что если вы попробуете, emptyList()вы получите тот же объект обратно.
Лоуренс Гонсалвес
4
это не лучший ответ, и определенно неправильный, нет гарантии, что будущие реализации могут измениться, если специально не задокументировано, что этот вызов метода всегда будет возвращать новую копию.
Bhargav
@BrunoJCM, это уже не так. В документации Kotlin указано, что toMutableList()возвращает новый список: «Возвращает новый MutableList, заполненный всеми элементами этой коллекции».
Пяр Нильс Амсен,
23
Ты можешь использовать
Список -> toList ()
Массив -> toArray ()
ArrayList -> toArray ()
MutableList -> toMutableList ()
Пример:
val array = arrayListOf("1","2","3","4")val arrayCopy = array.toArray()// copy array to other arrayLog.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
должен быть разделен на 2 ответа imho, так как я думаю, что первый правильный, но последнему не хватает красоты.
Хольгер Брандл
@Jacob Wu: Я был удивлен, увидев, что символ * во втором решении не вызывает ошибки. Что оно делает? Я сделал поиск с «унарным умножением», но ничего не нашел.
Lensflare
1
@Lensflare * означает разделение массива на отдельные элементы, например mutableListOf (* [1, 2, 3]) означает mutableListOf (1, 2, 3), это похоже на операцию, противоположную vararg
Джейкоб Ву
1
@ Джейкоб Ву: Спасибо. С вашим ответом я смог узнать, что этот оператор называется «оператор распространения». Я вижу, как это помогает, объединив некоторые параметры с массивом в список varargs. Но какая польза от этого в вашем примере? Это быстрее что ли? Или это ключ к копированию коллекции?
Lensflare
@Lensflare Я думаю, что преимущество заключается только в синтаксисе - код короткий, и явного общего типа не требуется (как в моем 1-м примере). Я считаю, что за кулисами код скомпилирован для операций с массивами, поэтому производительность должна быть такой же.
Вы можете использовать предоставленное расширение, Iterable.toMutableList()которое предоставит вам новый список. К сожалению, как следует из его подписи и документации , он предназначен для обеспечения того, чтобы объект Iterableбыл List(как toStringи многие другие to<type>методы). Ничто не гарантирует вам, что это будет новый список. Например, добавив следующую строку в начале расширения:if (this is List) return this является законным улучшением производительности (если оно действительно улучшает производительность).
Кроме того, из-за своего названия результирующий код не очень понятен.
Я предпочитаю добавить собственное расширение, чтобы быть уверенным в результате и создать гораздо более понятный код (как у нас для массивов ):
fun<T>List<T>.copyOf():List<T>{val original =thisreturn mutableListOf<T>().apply { addAll(original)}}fun<T>List<T>.mutableCopyOf():MutableList<T>{val original =thisreturn mutableListOf<T>().apply { addAll(original)}}
Обратите внимание, что addAllэто самый быстрый способ копирования, поскольку он использует собственный System.arraycopyв реализации ArrayList.
Мне нравится это решение. Разве не должно быть addAll(this@copyOf), потому что thisвнутри applyбудет ссылаться на только что созданный пустой список? Либо так, либо mutableListOf<T>().also { it.addAll(this) }?
Обратите внимание, что это не работает для Maps. Он компилируется, но, поскольку itэто a Map.Entry, а копия неглубокая, у вас есть те же записи.
noamtm
1
@noamtm да, это то, что я имею в виду под мелкой копией. Этот метод никогда не скопирует записи. Будет создана только копия коллекции с такими же записями. Карта здесь ничего особенного.
Lensflare
2
Я хочу сказать, что хотя заманчиво использовать его и на картах, он компилируется и, кажется, работает, на самом деле это не работает.
noamtm
4
Как и в 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.
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>>{varMatrResult=ArrayList<ArrayList<T>>()for(i in v.indices)MatrResult.add(v[i].clone()asArrayList<T>)returnMatrResult}
Демо для целочисленной матрицы:
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])
Ответы:
Это прекрасно работает.
источник
val selectedSeries = series.toList()
также работает, потому что требуетtoMutableList()
своей реализации.===
и должен сказать ,toList()
не копировать коллекции, ноtoMutableList()
делаетIterable.toList()
возвращаетсяemptyList()
, который всегда возвращает один и тот же (неизменяемый) объект. Так что если вы попробуете,emptyList()
вы получите тот же объект обратно.toMutableList()
возвращает новый список: «Возвращает новый MutableList, заполненный всеми элементами этой коллекции».Ты можешь использовать
Список -> toList ()
Массив -> toArray ()
ArrayList -> toArray ()
MutableList -> toMutableList ()
Пример:
распечатать журнал:
источник
Я могу предложить два альтернативных способа:
Обновление: с новым механизмом вывода типа (опция в Kotlin 1.3) мы можем опустить параметр общего типа в 1-м примере и получить следующее:
FYI. Способ включения нового вывода -
kotlinc -Xnew-inference ./SourceCode.kt
для командной строки илиkotlin { experimental { newInference 'enable'}
для Gradle. Для получения дополнительной информации о новом выводе типов посмотрите это видео: KotlinConf 2018 - Новый вывод типов и связанные с ним языковые функции от Светланы Исаковой , особенно «вывод для строителей» на 30-й странице.источник
Если ваш список содержит класс данных kotlin , вы можете сделать это
источник
Вы можете использовать предоставленное расширение,
Iterable.toMutableList()
которое предоставит вам новый список. К сожалению, как следует из его подписи и документации , он предназначен для обеспечения того, чтобы объектIterable
былList
(какtoString
и многие другиеto<type>
методы). Ничто не гарантирует вам, что это будет новый список. Например, добавив следующую строку в начале расширения:if (this is List) return this
является законным улучшением производительности (если оно действительно улучшает производительность).Кроме того, из-за своего названия результирующий код не очень понятен.
Я предпочитаю добавить собственное расширение, чтобы быть уверенным в результате и создать гораздо более понятный код (как у нас для массивов ):
Обратите внимание, что
addAll
это самый быстрый способ копирования, поскольку он использует собственныйSystem.arraycopy
в реализацииArrayList
.Также имейте в виду, что это даст вам только поверхностную копию .
источник
addAll(this@copyOf)
, потому чтоthis
внутриapply
будет ссылаться на только что созданный пустой список? Либо так, либоmutableListOf<T>().also { it.addAll(this) }
?Для мелкой копии я предлагаю
Это будет работать для многих типов коллекций.
источник
Map
s. Он компилируется, но, посколькуit
это aMap.Entry
, а копия неглубокая, у вас есть те же записи.Как и в Java:
Список:
Карта:
Предполагая, что вы ориентируетесь на JVM (или Android); Я не уверен, что он работает для других целей, поскольку он полагается на конструкторы копирования ArrayList и HashMap.
источник
Я хотел бы использовать в
toCollection()
метод расширения :Это создаст новый,
MutableList
а затем добавит каждый элемент оригинала во вновь созданный список.Предполагаемый тип здесь будет
MutableList<String>
. Если вы не хотите раскрывать изменчивость этого нового списка, вы можете явно объявить тип как неизменяемый список:источник
Для простых списков есть много правильных решений выше.
Однако это только для мелководных списков.
Приведенная ниже функция работает для любых двухмерных
ArrayList
.ArrayList
на практике эквивалентенMutableList
. Интересно, что это не работает при использовании явногоMutableList
типа. Если нужно больше измерений, нужно сделать больше функций.Демо для целочисленной матрицы:
это показывает
12
источник
Вы можете использовать
ArrayList
конструктор:ArrayList(list)
источник
Попробуйте ниже код для копирования списка в Котлине
источник