Comment copier la liste dans Kotlin?
j'utilise
val selectedSeries = mutableListOf<String>()
selectedSeries.addAll(series)
Y a-t-il un moyen plus simple?
Comment copier la liste dans Kotlin?
j'utilise
val selectedSeries = mutableListOf<String>()
selectedSeries.addAll(series)
Y a-t-il un moyen plus simple?
Réponses:
Cela fonctionne très bien.
val selectedSeries = series.toMutableList()
val selectedSeries = series.toList()
fonctionne aussi car il appelle toMutableList()
dans sa mise en œuvre.
===
et je dois dire toList()
qu'il ne copie pas la collection, mais le toMutableList()
fait
Iterable.toList()
renvoie emptyList()
, qui renvoie toujours le même objet (immuable). Donc, si vous testez avec, emptyList()
vous récupérerez le même objet.
toMutableList()
renvoie une nouvelle liste, "Renvoie une nouvelle MutableList remplie de tous les éléments de cette collection.".
Vous pouvez utiliser
Liste -> toList ()
Array -> toArray ()
ArrayList -> toArray ()
MutableList -> toMutableList ()
Exemple:
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())
journal d'impression:
array: 4
arrayCopy: 4
array after remove: 3
arrayCopy after remove: 4
Je peux proposer deux méthodes alternatives:
1. val selectedSeries = mutableListOf<String>().apply { addAll(series) }
2. val selectedSeries = mutableListOf(*series.toTypedArray())
Mise à jour: avec le nouveau moteur d'inférence de type (opt-in dans Kotlin 1.3), nous pouvons omettre le paramètre de type générique dans le 1er exemple et avoir ceci:
1. val selectedSeries = mutableListOf().apply { addAll(series) }
Pour votre information, la façon d'accepter une nouvelle inférence est kotlinc -Xnew-inference ./SourceCode.kt
pour la ligne de commande ou kotlin { experimental { newInference 'enable'}
pour Gradle. Pour plus d'informations sur la nouvelle Inférence de Type, regardez cette vidéo: KotlinConf 2018 - Nouvelle Inférence de Type et Fonctionnalités de Langage Associées par Svetlana Isakova , en particulier 'inférence pour les constructeurs' à 30 '
Si votre liste contient une classe de données kotlin , vous pouvez le faire
selectedSeries = ArrayList(series.map { it.copy() })
Vous pouvez utiliser l'extension fournie Iterable.toMutableList()
qui vous fournira une nouvelle liste. Malheureusement, comme le suggèrent sa signature et sa documentation , il est destiné à garantir que an Iterable
est un List
(comme toString
et de nombreuses autres to<type>
méthodes). Rien ne vous garantit que ce sera une nouvelle liste. Par exemple, ajouter la ligne suivante au début de l'extension: if (this is List) return this
est une amélioration légitime des performances (si elle améliore effectivement les performances).
De plus, à cause de son nom, le code résultant n'est pas très clair.
Je préfère ajouter ma propre extension pour être sûr du résultat et créer un code beaucoup plus clair (comme nous l'avons fait pour les tableaux ):
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) }
}
Notez que addAll
c'est le moyen le plus rapide de copier car il utilise le natif System.arraycopy
dans l'implémentation de ArrayList
.
Aussi, sachez que cela ne vous donnera qu'une copie superficielle .
addAll(this@copyOf)
, car this
inside apply
fera référence à la liste vide nouvellement créée? Soit ça ou mutableListOf<T>().also { it.addAll(this) }
?
Pour une copie superficielle, je suggère
.map{it}
Cela fonctionnera pour de nombreux types de collections.
Map
s. Il compile, mais puisque le it
est un Map.Entry
, et que la copie est superficielle, vous avez les mêmes entrées.
Tout comme en Java:
Liste:
val list = mutableListOf("a", "b", "c")
val list2 = ArrayList(list)
Carte:
val map = mutableMapOf("a" to 1, "b" to 2, "c" to 3)
val map2 = HashMap(map)
En supposant que vous ciblez la JVM (ou Android); Je ne suis pas sûr que cela fonctionne pour d'autres cibles, car il repose sur les constructeurs de copie d'ArrayList et HashMap.
J'utiliserais la toCollection()
méthode d'extension :
val original = listOf("A", "B", "C")
val copy = original.toCollection(mutableListOf())
Cela créera un nouveau MutableList
, puis ajoutera chaque élément de l'original à la liste nouvellement créée.
Le type déduit ici sera MutableList<String>
. Si vous ne souhaitez pas exposer la mutabilité de cette nouvelle liste, vous pouvez déclarer le type explicitement comme une liste immuable:
val copy: List<String> = original.toCollection(mutableListOf())
Pour les listes simples a de nombreuses bonnes solutions ci-dessus.
Cependant, c'est juste pour les listes peu profondes.
La fonction ci-dessous fonctionne pour n'importe quelle dimension 2 ArrayList
. ArrayList
est, en pratique, équivalent à MutableList
. Fait intéressant, cela ne fonctionne pas lors de l'utilisation de MutableList
type explicite . Si l'on a besoin de plus de dimensions, il faut faire plus de fonctions.
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
}
Démo pour la matrice entière:
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])
ça montre 12
Vous pouvez utiliser le ArrayList
constructeur:ArrayList(list)