val selectedSeries = series.toList()también funciona porque llama toMutableList()a su implementación.
Flávio Faria
4
@ FlávioFaria acaba de probarlo ===y tengo que decir toList()que no copia la colección, pero toMutableList()sí
Peppermint Paddy
3
@PeppermintPaddy Se hace copia, excepto en el caso de las listas vacías. Si la fuente está vacía, Iterable.toList()devuelve emptyList(), que siempre devuelve el mismo objeto (inmutable). Entonces, si prueba con emptyList(), obtendrá el mismo objeto.
Laurence Gonsalves
52
Personalmente, no me gusta esta idea ... Nada en la concesión de documentos que toMutableList()deba devolver una nueva instancia de una lista si la instancia que llama al método ya es una lista mutable.
BrunoJCM
4
esta no es una buena respuesta, y definitivamente no es la correcta, no hay garantía de que futuras implementaciones puedan cambiar, a menos que esté específicamente documentado que esta llamada al método siempre devolverá una nueva copia.
Bhargav
23
Puedes usar
Lista -> toList ()
Matriz -> toArray ()
ArrayList -> toArray ()
MutableList -> toMutableList ()
Ejemplo:
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())
registro de impresión:
array:4
arrayCopy:4
array after remove:3
arrayCopy after remove:4
Actualización: con el nuevo motor de inferencia de tipos (opt-in en Kotlin 1.3), podemos omitir el parámetro de tipo genérico en el primer ejemplo y tener esto:
Para su información, la forma de optar por la nueva Inferencia es kotlinc -Xnew-inference ./SourceCode.ktpara la línea de comandos o kotlin { experimental { newInference 'enable'}para Gradle. Para obtener más información sobre la nueva inferencia de tipos, consulte este video: KotlinConf 2018 - Nueva inferencia de tipos y características de lenguaje relacionadas de Svetlana Isakova , especialmente 'inferencia para constructores' en 30 '
debería dividirse en 2 respuestas en mi humilde opinión, ya que creo que la primera es correcta, pero la última carece de algo de belleza.
Holger Brandl
@Jacob Wu: Me sorprendió ver que el símbolo * en la segunda solución no producía un error. ¿Qué hace? Hice una búsqueda con "multiplicación unaria" pero no encontré nada.
Lensflare
1
@Lensflare * significa destruir una matriz en elementos separados, por ejemplo, mutableListOf (* [1, 2, 3]) significa mutableListOf (1, 2, 3), es como la operación opuesta a vararg
Jacob Wu
1
@Jacob Wu: Gracias. Con su respuesta, pude descubrir que el operador se llama "operador de propagación". Veo cómo ayuda combinar algunos parámetros con una matriz en una lista de varargs. Pero, ¿qué beneficio tiene en tu ejemplo? ¿Es más rápido o algo así? ¿O es la clave para asegurarse de que se copia la colección?
Lensflare
@Lensflare Creo que el beneficio es solo la sintaxis: el código es corto y no se requiere un tipo genérico explícito (como en mi primer ejemplo). Detrás de escena, creo que el código se compila para operaciones de matriz, por lo que el rendimiento debería ser el mismo.
Puede utilizar la extensión provista Iterable.toMutableList()que le proporcionará una nueva lista. Desafortunadamente, como sugiere su firma y documentación , está destinado a garantizar que an Iterablees un List(como toStringy muchos otros to<type>métodos). Nada te garantiza que será una nueva lista. Por ejemplo, agregar la siguiente línea al comienzo de la extensión: if (this is List) return thises una mejora legítima del desempeño (si es que realmente mejora el desempeño).
Además, debido a su nombre, el código resultante no es muy claro.
Prefiero agregar mi propia extensión para estar seguro del resultado y crear un código mucho más claro (como tenemos para las matrices ):
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)}}
Tenga en cuenta que addAlles la forma más rápida de copiar porque usa el nativo System.arraycopyen la implementación de ArrayList.
Además, tenga en cuenta que esto solo le dará una copia superficial .
Me gusta esta solucion ¿No debería ser así addAll(this@copyOf), porque thisdentro applyse referirá a la lista vacía recién creada? ¿O eso o mutableListOf<T>().also { it.addAll(this) }?
Tenga en cuenta que no funciona para Maps. Se compila, pero como ites a Map.Entry, y la copia es poco profunda, tiene las mismas entradas.
noamtm
1
@noamtm sí, eso es lo que quiero decir con copia superficial. Este método nunca copiará las entradas. Solo hará una copia de la colección con las mismas entradas. El mapa no es nada especial aquí.
Lensflare
2
Mi punto es que, aunque también es tentador usarlo en mapas, y se compila y parece funcionar, en realidad no funciona.
noamtm
4
Como en Java:
Lista:
val list = mutableListOf("a","b","c")val list2=ArrayList(list)
Mapa:
val map = mutableMapOf("a" to 1,"b" to 2,"c" to 3)val map2=HashMap(map)
Suponiendo que está apuntando a la JVM (o Android); No estoy seguro de que funcione para otros objetivos, ya que se basa en los constructores de copia de ArrayList y HashMap.
val original = listOf("A","B","C")val copy = original.toCollection(mutableListOf())
Esto creará un nuevo MutableListy luego agregará cada elemento del original a la lista recién creada.
El tipo inferido aquí será MutableList<String>. Si no desea exponer la mutabilidad de esta nueva lista, puede declarar el tipo explícitamente como una lista inmutable:
val copy:List<String>= original.toCollection(mutableListOf())
Para listas simples tiene muchas soluciones correctas arriba.
Sin embargo, es solo para listas poco profundas.
La siguiente función funciona para cualquier bidimensional ArrayList. ArrayListes, en la práctica, equivalente a MutableList. Curiosamente, no funciona cuando se usa un MutableListtipo explícito . Si se necesitan más dimensiones, es necesario realizar más funciones.
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}
Demostración para matriz de enteros:
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])
Respuestas:
Esto funciona bien.
fuente
val selectedSeries = series.toList()
también funciona porque llamatoMutableList()
a su implementación.===
y tengo que decirtoList()
que no copia la colección, perotoMutableList()
síIterable.toList()
devuelveemptyList()
, que siempre devuelve el mismo objeto (inmutable). Entonces, si prueba conemptyList()
, obtendrá el mismo objeto.toMutableList()
deba devolver una nueva instancia de una lista si la instancia que llama al método ya es una lista mutable.Puedes usar
Lista -> toList ()
Matriz -> toArray ()
ArrayList -> toArray ()
MutableList -> toMutableList ()
Ejemplo:
registro de impresión:
fuente
Puedo pensar en dos formas alternativas:
Actualización: con el nuevo motor de inferencia de tipos (opt-in en Kotlin 1.3), podemos omitir el parámetro de tipo genérico en el primer ejemplo y tener esto:
Para su información, la forma de optar por la nueva Inferencia es
kotlinc -Xnew-inference ./SourceCode.kt
para la línea de comandos okotlin { experimental { newInference 'enable'}
para Gradle. Para obtener más información sobre la nueva inferencia de tipos, consulte este video: KotlinConf 2018 - Nueva inferencia de tipos y características de lenguaje relacionadas de Svetlana Isakova , especialmente 'inferencia para constructores' en 30 'fuente
Si su lista contiene la clase de datos kotlin , puede hacer esto
fuente
Puede utilizar la extensión provista
Iterable.toMutableList()
que le proporcionará una nueva lista. Desafortunadamente, como sugiere su firma y documentación , está destinado a garantizar que anIterable
es unList
(comotoString
y muchos otrosto<type>
métodos). Nada te garantiza que será una nueva lista. Por ejemplo, agregar la siguiente línea al comienzo de la extensión:if (this is List) return this
es una mejora legítima del desempeño (si es que realmente mejora el desempeño).Además, debido a su nombre, el código resultante no es muy claro.
Prefiero agregar mi propia extensión para estar seguro del resultado y crear un código mucho más claro (como tenemos para las matrices ):
Tenga en cuenta que
addAll
es la forma más rápida de copiar porque usa el nativoSystem.arraycopy
en la implementación deArrayList
.Además, tenga en cuenta que esto solo le dará una copia superficial .
fuente
addAll(this@copyOf)
, porquethis
dentroapply
se referirá a la lista vacía recién creada? ¿O eso omutableListOf<T>().also { it.addAll(this) }
?Para una copia superficial, sugiero
Eso funcionará para muchos tipos de colecciones.
fuente
Map
s. Se compila, pero comoit
es aMap.Entry
, y la copia es poco profunda, tiene las mismas entradas.Como en Java:
Lista:
Mapa:
Suponiendo que está apuntando a la JVM (o Android); No estoy seguro de que funcione para otros objetivos, ya que se basa en los constructores de copia de ArrayList y HashMap.
fuente
Usaría el
toCollection()
método de extensión :Esto creará un nuevo
MutableList
y luego agregará cada elemento del original a la lista recién creada.El tipo inferido aquí será
MutableList<String>
. Si no desea exponer la mutabilidad de esta nueva lista, puede declarar el tipo explícitamente como una lista inmutable:fuente
Para listas simples tiene muchas soluciones correctas arriba.
Sin embargo, es solo para listas poco profundas.
La siguiente función funciona para cualquier bidimensional
ArrayList
.ArrayList
es, en la práctica, equivalente aMutableList
. Curiosamente, no funciona cuando se usa unMutableList
tipo explícito . Si se necesitan más dimensiones, es necesario realizar más funciones.Demostración para matriz de enteros:
muestra
12
fuente
Puedes usar el
ArrayList
constructor:ArrayList(list)
fuente
Pruebe el siguiente código para copiar la lista en Kotlin
fuente