Nous sommes tombés, dans le cadre d'un ticket de support, sur une problématique intéressante, probablement déjà connue de nombreux développeurs Java et connaisseurs des subtilités de ses APIs, mais qui n'en demeure pas moins, disons... "sympathique".
Il s'agit de la fonction très utile, et très utilisée, permettant de passer d'un tableau ( X[] ) en une Collection<X> d'objets, afin de pouvoir y appliquer des opérations telles que des itérations, des tris et autres : la méthode Arrays.asList()
Il est très important de savoir qu'une modification de la liste retournée modifiera aussi le tableau de départ !
Par exemple, soit le code très simple suivant :
String[] myChoices = new String[] { "toto", "titi", "tata" };
List<String> theChoices = Arrays.asList(myChoices);
Collections.sort(theChoices);
for (String iterChoice : myChoices) { System.out.println(iterChoice); }
Quel sera le résultat retourné (affichage des éléments du tableau de départ) ? Celui-ci :
tata
titi
toto
- De même, modifier un élément de la Collection (via la méthode Collection.set() par exemple) modifiera l'élément correspondant dans le tableau.
- Par contre, on ne peut pas ajouter ou supprimer des éléments à cette Collection (cf. méthodes Collection.add() et Collection.remove() ).
Conséquence directe, pratique et redoutable dans JCMS : si, dans les IHMs d'une application :
- un contenu est affiché dans un écran, en présentant certains de ces champs selon un ordre donné,
- si ce même ordre est retrouvé à tort dans un autre écran (y compris en back-office),
- et en général, si tout revient en ordre après un redémarrage de JCMS (jusqu'à l'affichage du fameux écran du premier point),
il faut chercher la solution de ce côté-ci : le contenu de l'objet aura en effet probablement été modifié en mémoire, suite à un Arrays.asList() appliqué au retour d'un appel get() de cet objet, et placé dans une Collection sur laquelle un tri aura été directement effectué...
Bon à savoir donc... ;-)
Je me suis permis de rajouter la partie "Conséquence directe...dans JCMS", car c'est bien ce qui nous intéresse et est réellement important dans notre cadre, après la partie "théorique".
Bon à savoir en effet!
Nous avons rencontré justement ce problème.
Nous avions un objet avec un champ multivalué vers un autre contenu.
Lorsque nous faisions:
obj.getVideo()
=> [Video 3, Video 1, Video 2]=> Le 1er affichage de ce "nouveau" était correct.
=> Lors d'un F5,
obj.getVideo()
nous retournait: -> [Video 1, Video 2, Video 3] alors que dans le store l'ordre n'était pas celui là mais [Video 3, Video 1, Video 2]. Le problème se situait lors de la copie du fameux tableau avec le == = == Il nous a donc fallu copier ce tableau à "l'ancienne" en bouclant sur le tableau retourné par l'objet JCMS et y insérer dans le nouveau tableau, les valeurs une à une!