ArrayList<String> en String[] : ne vous laissez pas tromper
\n\nSalut, ami ! Si tu lis ceci, c'est que tu as déjà rencontré le problème classique : transformer un ArrayList<String> en un tableau standard String[]. Que pourrait-il mal se passer, apparemment ? Tu prends la méthode toArray(), tu l'appelles, et le tour est joué. Mais détrompe-toi ! Java est un langage sournois, et même une opération aussi simple peut devenir un casse-tête si tu ne connais pas les pièges.
Sur Stack Overflow, cette question a recueilli des milliers de vues, et ce n'est pas pour rien. Nous avons rassemblé les 5 principales erreurs que même les développeurs expérimentés commettent, et nous montrons comment les éviter. C'est parti !
\n\nPourquoi list.toArray() ne fonctionne-t-il pas simplement ?
\n\nAllons droit au but. Tu as une liste :
\n\nArrayList<String> list = new ArrayList<>();\nlist.add("Java");\nlist.add("Python");\nlist.add("C++");\n\nTu veux obtenir un tableau de chaînes. La première idée est d'appeler list.toArray(). Regarde ce qui se passe :
Object[] objectArray = list.toArray(); // Fonctionne, mais retourne Object[]\n// String[] stringArray = list.toArray(); // Erreur de compilation !\n\nErreur n°1 : oublier le transtypage. La méthode toArray() sans arguments retourne un Object[], pas un String[]. Le compilateur ne te permettra pas d'assigner un Object[] à une variable de type String[] sans conversion explicite :
String[] stringArray = (String[]) list.toArray(); // ClassCastException à l'exécution !\n\nC'est là que les choses deviennent intéressantes. La deuxième erreur est de penser que le transtypage va sauver la mise. Tu obtiendras une ClassCastException, car en interne, toArray() crée un tableau de type Object[], pas String[]. Le cast ne change pas le type de l'objet – il dit simplement au compilateur : « Fais-moi confiance, c'est une chaîne ». Et Java, à l'exécution, vérifie et lève une exception.
La bonne méthode : toArray(new String[0])
\n\nLa méthode la plus courante et correcte est de passer un tableau vide du type souhaité à toArray() :
String[] stringArray = list.toArray(new String[0]);\n\nPourquoi cela fonctionne-t-il ? Parce que la méthode toArray(T[] a) est une méthode générique. Elle accepte un tableau de type T et retourne un tableau du même type. Si le tableau passé n'est pas assez grand, la méthode crée un nouveau tableau du type correct par réflexion. Si la taille convient, elle le remplit.
Erreur n°3 : passer un tableau de taille incorrecte. Certains débutants écrivent :
\n\nString[] stringArray = list.toArray(new String[list.size()]);\n\nCela fonctionne aussi, mais examinons ce qui est mieux. Lorsque nous passons un tableau de taille list.size(), la méthode le remplit et le retourne. Si nous passons new String[0], un nouveau tableau est créé. Apparemment, pourquoi perdre du temps à créer un nouveau tableau ? En réalité, la JVM optimise la création d'un tableau vide, et dans la plupart des cas, new String[0] est plus rapide que new String[list.size()]. Pourquoi ? Parce que dans le second cas, le tableau est créé, puis rempli de valeurs null, puis réécrit. Du travail supplémentaire.
Les JVM modernes (Java 8+) optimisent souvent new String[0] en une constante, ce qui le rend plus rapide. Mais si tu travailles avec Java 6 ou 7, la différence peut être notable. Dans tous les cas, la meilleure pratique est d'utiliser new String[0], sauf si une performance extrêmement élevée est requise. Pour les sections de code critiques en termes de vitesse, teste les deux options.
Piège : synchronisation et multithreading
\n\nErreur n°4 : conversion dans un environnement multithread sans synchronisation. Imagine : tu as un ArrayL