Collections


L'API de collection est séparée en 2 types de fonctionnalités : les collections à proprement parler avec les interfaces Collection, List, Set et leurs sous interfaces, et les maps. Les bonnes pratiques imposent de déclarer les variables avec une interface et de n'utiliser les classes que pour l'instanciation.

Classes et interfaces

Les couples classe / interface classiques sont les suivants :

 Collection col = new ArrayList();
 List list = new ArrayList();
 Set set = new HashSet();
 Map map = new HashMap();

L'utilisation de classes anciennes, comme Vector ou Hashtable, est généralement à proscrire.

Boucles for each

Depuis Java SE 5, une nouvelle forme de boucle for, surnommée « for each » a été introduite. Elle est beaucoup plus pratique que l'ancienne forme, mais présente des contraintes lorsqu'on veut manipuler la collection qu'on parcourt car l'itérateur n'est pas accessible.

 for (Type var : aCollection) {
   aCollection.remove(var); // Ceci est interdit !!!
 }

Le problème rencontré est une ConcurrentAccessException lorsqu'on supprime un élément de la collection en cours d'itération. L'ancienne boucle, du fait qu'elle sépare distinctement la collection de son itérateur, permet d'ajouter ou de retirer depuis le corps de la boucle de éléments de la collection. Ceci fonctionne à condition de la faire via l'itérateur et non directement sur la collection.

 for (Iterator<Type> it = aCollection.iterator();it.hasNext();) {
   Type var =  it.next();
   ...
   aCollection.remove(var); // Ceci est toujours interdit
   it.remove(); // Ceci est autorisé
   ...
 }


Tri

Le tri d'une liste se fait en passant la liste à trier à la méthode java.util.Collections.sort(list). Cette méthode trie les objets de la liste selon le résultat de leurs méthodes compareTo(). Cela signifie donc que ces objets doivent implémenter l'interface Comparable.

Pour trier des listes d'objets qui n'implémente pas cette interface, on peut choisir de développer un Comparator dédié et en passer une instance à la méthode java.util.Collections.sort(list, comparator). On trouvera des comparateurs intéressants, prêts à l'emploi, dans les librairies common-beanutils et common-collections du projet Apache Jakarta.

On notera toutefois que Apache Commons Collections v3 ne supporte pas la notation generics de Java 5. Pour ce support on se tournera vers la branche proposée sur sourceforge, ou vers des concurrents comme jAggregate ou Google.

Performances

Liste

Les 2 implémentations couramment comparées sont ArrayList et LinkedList. Si deux implémentations existent, c'est qu'elles ont chacune des avantages et inconvénients. Donc dans quel cas LinkedList est préférable ?

Le cas le plus classique d'utilisation des listes est l'ajout d'objets en fin de liste, puis une itération de cette même liste, du début à la fin. Pour cette utilisation, il semble que ArrayList est systématiquement meilleur, quelle que soit la taille de la liste.

Le seul cas où LinkedList est généralement meilleur, c'est quand on modifie les éléments intermédiaires de la liste : ajout ou suppression d'objets en début ou au milieu de la liste.