Risposte:
Funziona bene.
val selectedSeries = series.toMutableList()
val selectedSeries = series.toList()
funziona anche perché chiama toMutableList()
nella sua implementazione.
===
e devo dire toList()
che non copia la raccolta, ma lo toMutableList()
fa
Iterable.toList()
restituisce emptyList()
, che restituisce sempre lo stesso oggetto (immutabile). Quindi, se provi con emptyList()
, riavrai indietro lo stesso oggetto.
toMutableList()
dovrebbe restituire una nuova istanza di un elenco se l'istanza che chiama il metodo è già un elenco modificabile.
Puoi usare
List -> toList ()
Array -> toArray ()
ArrayList -> toArray ()
MutableList -> toMutableList ()
Esempio:
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())
registro di stampa:
array: 4
arrayCopy: 4
array after remove: 3
arrayCopy after remove: 4
Posso trovare due modi alternativi:
1. val selectedSeries = mutableListOf<String>().apply { addAll(series) }
2. val selectedSeries = mutableListOf(*series.toTypedArray())
Aggiornamento: con il nuovo motore di inferenza del tipo (opt-in in Kotlin 1.3), possiamo omettere il parametro di tipo generico nel 1 ° esempio e avere questo:
1. val selectedSeries = mutableListOf().apply { addAll(series) }
Cordiali saluti, il modo per attivare la nuova inferenza è kotlinc -Xnew-inference ./SourceCode.kt
per la riga di comando o kotlin { experimental { newInference 'enable'}
per Gradle. Per maggiori informazioni sulla nuova inferenza del tipo, guarda questo video: KotlinConf 2018 - Nuova inferenza del tipo e funzionalità del linguaggio correlato di Svetlana Isakova , in particolare 'inferenza per i costruttori' a 30 '
Se la tua lista contiene la classe di dati kotlin , puoi farlo
selectedSeries = ArrayList(series.map { it.copy() })
Puoi utilizzare l'estensione fornita Iterable.toMutableList()
che ti fornirà un nuovo elenco. Sfortunatamente, come suggeriscono la sua firma e la documentazione , ha lo scopo di garantire che an Iterable
sia a List
(proprio come toString
e molti altri to<type>
metodi). Niente ti garantisce che sarà una nuova lista. Ad esempio, l'aggiunta della seguente riga all'inizio dell'estensione: if (this is List) return this
è un legittimo miglioramento delle prestazioni (se effettivamente migliora le prestazioni).
Inoltre, a causa del suo nome, il codice risultante non è molto chiaro.
Preferisco aggiungere la mia estensione per essere sicuro del risultato e creare un codice molto più chiaro (proprio come abbiamo per gli array ):
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) }
}
Nota che addAll
è il modo più veloce per copiare perché utilizza il nativo System.arraycopy
nell'implementazione di ArrayList
.
Inoltre, fai attenzione che questo ti darà solo una copia superficiale .
addAll(this@copyOf)
, perché this
all'interno apply
farà riferimento alla lista vuota appena creata? O quello o mutableListOf<T>().also { it.addAll(this) }
?
Per una copia superficiale, suggerisco
.map{it}
Funzionerà per molti tipi di raccolta.
Map
s. Viene compilato, ma poiché it
è a Map.Entry
e la copia è superficiale, hai le stesse voci.
Proprio come in Java:
Elenco:
val list = mutableListOf("a", "b", "c")
val list2 = ArrayList(list)
Carta geografica:
val map = mutableMapOf("a" to 1, "b" to 2, "c" to 3)
val map2 = HashMap(map)
Supponendo che tu stia prendendo di mira la JVM (o Android); Non sono sicuro che funzioni per altri obiettivi, poiché si basa sui costruttori di copia di ArrayList e HashMap.
Userei il toCollection()
metodo di estensione :
val original = listOf("A", "B", "C")
val copy = original.toCollection(mutableListOf())
Questo creerà un nuovo MutableList
e quindi aggiungerà ogni elemento dell'originale all'elenco appena creato.
Il tipo dedotto qui sarà MutableList<String>
. Se non vuoi esporre la mutabilità di questo nuovo elenco, puoi dichiarare il tipo esplicitamente come un elenco immutabile:
val copy: List<String> = original.toCollection(mutableListOf())
Per elenchi semplici ha molte soluzioni giuste sopra.
Tuttavia, è solo per gli elenchi dei fondali bassi.
La funzione seguente funziona per qualsiasi bidimensionale ArrayList
. ArrayList
è, in pratica, equivalente a MutableList
. È interessante notare che non funziona quando si utilizza il MutableList
tipo esplicito . Se sono necessarie più dimensioni, è necessario creare più funzioni.
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
}
Demo per matrice intera:
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])
mostra 12
Puoi usare il ArrayList
costruttore:ArrayList(list)