Clonage de listes en Kotlin : comment éviter les pièges avec les références ?
\n\nImaginez : vous développez une application en Kotlin, vous traitez une liste de données, et soudainement le tableau d'origine se modifie tout seul. Un problème familier ? Vous avez probablement copié la référence, et non la liste elle-même. Dans cet article, nous allons passer en revue toutes les méthodes légales pour cloner une liste en Kotlin — de la copie superficielle à la copie profonde. Sans blabla, uniquement du code et des explications.
\n\nCe sujet s'inspire d'une question populaire sur Stack Overflow (plus de 200 000 vues) : "How to clone or copy a list in kotlin". Mettons les choses au clair une fois pour toutes sur la façon de copier une liste Kotlin pour ne pas perdre de données et ne pas devenir fou.
\n\nPourquoi une simple affectation ne fonctionne-t-elle pas ?
\n\nEn Kotlin, comme en Java, les listes sont des types références. Si vous écrivez :
\n\nval original = mutableListOf("A", "B", "C")\nval copy = original // Ce n'est PAS une copie !\ncopy.add("D")\nprintln(original) // [A, B, C, D] — l'original a changé !\n\nVous avez simplement créé une deuxième référence vers le même objet en mémoire. Toute modification via copy affectera original. Pour éviter cela, vous devez utiliser des méthodes spéciales de copie de liste Kotlin.
Top 5 des méthodes pour copier une liste en Kotlin
\n\nNous allons examiner toutes les options principales : de la simple toList() à la copie profonde manuelle. Choisissez celle qui convient à votre tâche.
1. toList() — la méthode la plus simple
\n\nLa méthode toList() crée une nouvelle copie immuable de la liste. Il s'agit d'une copie superficielle (shallow copy) — les éléments eux-mêmes ne sont pas dupliqués, mais la structure de la liste devient indépendante.
val original = listOf("Kotlin", "Java", "Python")\nval copy = original.toList()\n\n// copy est un nouvel objet\nprintln(copy === original) // false — références différentes\nprintln(copy == original) // true — contenu identique\n\nIdéal pour les listes simples de chaînes ou de nombres. Si vous avez besoin d'une copie modifiable, utilisez toMutableList().
2. toMutableList() — pour les copies modifiables
\n\nVous voulez une copie que vous pouvez modifier ? toMutableList() est votre choix. Il crée une nouvelle MutableList avec les mêmes éléments.
val original = listOf(1, 2, 3)\nval mutableCopy = original.toMutableList()\nmutableCopy.add(4)\n\nprintln(original) // [1, 2, 3]\nprintln(mutableCopy) // [1, 2, 3, 4] — l'original n'est pas touché\n\nC'est la méthode la plus populaire pour cloner une mutable list en Kotlin.
\n\n3. ArrayList(collection) — le classique Java
\n\nSi vous venez de Java, cette méthode vous semblera familière. Le constructeur ArrayList prend une autre collection et copie ses éléments.
val original = listOf("A", "B", "C")\nval arrayCopy = ArrayList(original)\narrayCopy[0] = "Z"\n\nprintln(original) // [A, B, C]\nprintln(arrayCopy) // [Z, B, C]\n\nFonctionne rapidement et de manière prévisible. Mais rappelez-vous : c'est aussi une shallow copy.
\n\n4. map() — avec transformation des éléments
\n\nSi vous avez besoin non seulement de copier, mais aussi de transformer les éléments, utilisez map(). Il crée une nouvelle liste basée sur l'ancienne, en appliquant une lambda à chaque élément.
val numbers = listOf(10, 20, 30)\nval doubled = numbers.map { it * 2 }\n\nprintln(numbers) // [10, 20, 30]\nprintln(doubled) // [20, 40, 60]\n\nPour une simple copie sans modification, vous pouvez écrire numbers.map { it }, mais c'est redondant — il est préférable d'utiliser toList().
5. Copie profonde (deep copy) pour les objets complexes
\n\nToutes les méthodes précédentes effectuent une copie superficielle. Si votre liste contient des objets modifiables (par exemple, une data class avec des champs), la modification d'un objet dans la copie affectera l'original :