Transformons un tableau en ArrayList : pourquoi c'est un casse-tête récurrent pour les développeurs Java
\n\nQuiconque a déjà écrit en Java a été confronté à cette situation : vous avez un tableau prêt String[] ou int[], mais la tâche nécessite un ArrayList flexible avec ses méthodes add(), remove() et sa taille dynamique. Cela semble anodin, mais c'est précisément cette question qui a rassemblé des dizaines de milliers de vues et une multitude de votes sur Stack Overflow. Pourquoi ? Parce que, comme c'est souvent le cas en Java, il existe une solution « évidente » qui cache des pièges.
Dans cet article, nous ne nous contenterons pas de vous donner du code prêt à l'emploi. Nous passerons en revue toutes les méthodes de création d'un ArrayList à partir d'un tableau en Java, en analysant leurs avantages et inconvénients, leurs performances et, surtout, quand utiliser chaque option. Après avoir lu cet article, vous serez en mesure de choisir en toute confiance l'outil adapté à votre tâche et d'éviter une UnsupportedOperationException au moment le plus inattendu.
C'est parti ! (ou comme disent les javistes — let's dive into the code)
\n\nMéthode 1 : La classique — Arrays.asList()
\n\nLa méthode la plus populaire et la plus courte. Vous l'avez probablement déjà vue :
\n\nString[] fruits = {"apple", "banana", "cherry"};\nList<String> fruitList = Arrays.asList(fruits);\n\nÇa a l'air sympa, non ? Mais il y a un hic. La méthode Arrays.asList() ne retourne pas un java.util.ArrayList, mais sa propre version statique interne — java.util.Arrays.ArrayList. Il s'agit d'une liste de taille fixe qui ne supporte pas les opérations de redimensionnement. Si vous essayez de faire fruitList.add("date"), vous obtiendrez une UnsupportedOperationException.
Avantages :
\n- \n
- Code extrêmement court et lisible. \n
- Fonctionne comme un pont entre un tableau et l'API des collections. \n
- Les modifications dans la liste se répercutent sur le tableau d'origine (et vice versa). \n
Inconvénients :
\n- \n
- Taille fixe — impossible d'ajouter ou de supprimer des éléments. \n
- La liste retournée est une « enveloppe » autour du tableau, pas un ArrayList complet. \n
Quand l'utiliser : Lorsque vous avez besoin d'une liste en lecture seule, ou lorsque vous êtes certain que la taille ne changera pas. Par exemple, pour la passer à une méthode qui accepte List<?> et ne la modifie pas.
Comment obtenir un ArrayList complet à partir d'Arrays.asList() ?
\n\nIl suffit d'encapsuler le résultat dans un constructeur :
\n\nString[] fruits = {"apple", "banana", "cherry"};\nArrayList<String> fruitList = new ArrayList<>(Arrays.asList(fruits));\nfruitList.add("date"); // Fonctionne maintenant sans erreur\n\nCette astuce est un juste milieu. Vous utilisez la notation courte Arrays.asList, mais vous obtenez une collection dynamique complète.
Méthode 2 : Collections.addAll() — rapidité et contrôle
\n\nSi vous recherchez la performance ou si vous voulez simplement éviter une double copie (d'abord dans une liste de taille fixe, puis dans un ArrayList), il existe la méthode Collections.addAll() :
String[] fruits = {"apple", "banana", "cherry"};\nArrayList<String> fruitList = new ArrayList<>(fruits.length);\nCollections.addAll(fruitList, fruits);\n\nQue se passe-t-il ici ? Nous créons directement un ArrayList avec la taille initiale appropriée (pour éviter les redimensionnements inutiles du tableau interne), puis nous copions tous les éléments en une seule passe. La méthode addAll est plus rapide qu'une boucle for, car elle appelle System.arraycopy() à un niveau bas.
Avantages :
\n- \n
- Grande rapidité — presque au niveau d'une copie mémoire directe. \n
- On obtient immédiatement un ArrayList complet et modifiable. \n
- Possibilité de définir la capacité initiale de la liste. \n
Inconvénients :
\n- \n
- Le code est lég