val selectedSeries = series.toList()fonctionne aussi car il appelle toMutableList()dans sa mise en œuvre.
Flávio Faria
4
@ FlávioFaria vient de le tester avec ===et je dois dire toList()qu'il ne copie pas la collection, mais le toMutableList()fait
Peppermint Paddy
3
@PeppermintPaddy Il ne copie, sauf dans le cas des listes vides. Si la source est vide, 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.
Laurence Gonsalves
4
ce n'est pas une bonne réponse, et certainement pas la bonne, il n'y a aucune garantie que les futures implémentations pourraient changer, à moins qu'il ne soit spécifiquement documenté que cet appel de méthode retournera toujours une nouvelle copie.
Bhargav
@BrunoJCM, ce n'est plus le cas. L'état de la documentation Kotlin qui toMutableList()renvoie une nouvelle liste, "Renvoie une nouvelle MutableList remplie de tous les éléments de cette collection.".
Pär Nils Amsen le
23
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 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())
journal d'impression:
array:4
arrayCopy:4
array after remove:3
arrayCopy after remove:4
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:
devrait être divisé en 2 réponses à mon humble avis, car je pense que la première est correcte, mais la dernière manque de beauté.
Holger Brandl
@Jacob Wu: J'ai été surpris de voir que le symbole * dans la deuxième solution ne produisait pas d'erreur. Qu'est ce que ça fait? J'ai fait une recherche avec "multiplication unaire" mais je n'ai rien trouvé.
Lensflare
1
@Lensflare * signifie détruire un tableau en éléments séparés, par exemple mutableListOf (* [1, 2, 3]) signifie mutableListOf (1, 2, 3), c'est comme l'opération opposée à vararg
Jacob Wu
1
@Jacob Wu: Merci. Avec votre réponse, j'ai pu découvrir que l'opérateur s'appelle «opérateur de diffusion». Je vois comment cela aide en combinant certains paramètres avec un tableau dans une liste de varargs. Mais quel avantage cela a-t-il dans votre exemple? Est-ce plus rapide ou quelque chose? Ou est-ce la clé pour s'assurer que la collection est copiée?
Lensflare
@Lensflare Je pense que l'avantage est juste la syntaxe - le code est court et aucun type générique explicite n'est requis (comme dans mon premier exemple). En coulisse, je crois que le code est compilé pour des opérations de tableau, donc les performances devraient être les mêmes.
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 Iterableest un List(comme toStringet 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 thisest 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 =thisreturn mutableListOf<T>().apply { addAll(original)}}fun<T>List<T>.mutableCopyOf():MutableList<T>{val original =thisreturn mutableListOf<T>().apply { addAll(original)}}
Notez que addAllc'est le moyen le plus rapide de copier car il utilise le natif System.arraycopydans l'implémentation de ArrayList.
J'aime cette solution. Cela ne devrait-il pas être le cas addAll(this@copyOf), car thisinside applyfera référence à la liste vide nouvellement créée? Soit ça ou mutableListOf<T>().also { it.addAll(this) }?
Franko Leon Tokalić le
5
Pour une copie superficielle, je suggère
.map{it}
Cela fonctionnera pour de nombreux types de collections.
Notez que cela ne fonctionne pas pour Maps. Il compile, mais puisque le itest un Map.Entry, et que la copie est superficielle, vous avez les mêmes entrées.
noamtm
1
@noamtm oui, c'est ce que je veux dire par copie superficielle. Cette méthode ne copiera jamais les entrées. Il ne fera qu'une copie de la collection avec les mêmes entrées. La carte n'a rien de spécial ici.
Lensflare
2
Ce que je veux dire, c'est que même s'il est tentant de l'utiliser aussi sur des cartes, et qu'il se compile et semble fonctionner, cela ne fonctionne pas vraiment.
noamtm
4
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.
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. ArrayListest, en pratique, équivalent à MutableList. Fait intéressant, cela ne fonctionne pas lors de l'utilisation de MutableListtype 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>>{varMatrResult=ArrayList<ArrayList<T>>()for(i in v.indices)MatrResult.add(v[i].clone()asArrayList<T>)returnMatrResult}
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])
Réponses:
Cela fonctionne très bien.
la source
val selectedSeries = series.toList()
fonctionne aussi car il appelletoMutableList()
dans sa mise en œuvre.===
et je dois diretoList()
qu'il ne copie pas la collection, mais letoMutableList()
faitIterable.toList()
renvoieemptyList()
, 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:
journal d'impression:
la source
Je peux proposer deux méthodes alternatives:
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:
Pour votre information, la façon d'accepter une nouvelle inférence est
kotlinc -Xnew-inference ./SourceCode.kt
pour la ligne de commande oukotlin { 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 'la source
Si votre liste contient une classe de données kotlin , vous pouvez le faire
la source
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 anIterable
est unList
(commetoString
et de nombreuses autresto<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 ):
Notez que
addAll
c'est le moyen le plus rapide de copier car il utilise le natifSystem.arraycopy
dans l'implémentation deArrayList
.Aussi, sachez que cela ne vous donnera qu'une copie superficielle .
la source
addAll(this@copyOf)
, carthis
insideapply
fera référence à la liste vide nouvellement créée? Soit ça oumutableListOf<T>().also { it.addAll(this) }
?Pour une copie superficielle, je suggère
Cela fonctionnera pour de nombreux types de collections.
la source
Map
s. Il compile, mais puisque leit
est unMap.Entry
, et que la copie est superficielle, vous avez les mêmes entrées.Tout comme en Java:
Liste:
Carte:
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.
la source
J'utiliserais la
toCollection()
méthode d'extension :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:la source
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 deMutableList
type explicite . Si l'on a besoin de plus de dimensions, il faut faire plus de fonctions.Démo pour la matrice entière:
ça montre
12
la source
Vous pouvez utiliser le
ArrayList
constructeur:ArrayList(list)
la source
Essayez ci-dessous le code pour copier la liste à Kotlin
la source