Différence entre Collection et Collections en Java
Deux noms très similaires et une source de confusion classique : java.util.Collection et java.util.Collections. Le premier est une interface, le second une classe utilitaire. Les deux sont au cœur du Java Collections Framework mais remplissent des rôles opposés.
Collection — l'interface racine
Collection<E> est l'interface dont héritent toutes les structures de données : List, Set, Queue. Elle définit les opérations de base applicables à tout groupe d'éléments.
public interface Collection<E> extends Iterable<E> {
boolean add(E e);
boolean remove(Object o);
int size();
boolean contains(Object o);
boolean isEmpty();
void clear();
Iterator<E> iterator();
// ...
}
On l'utilise comme type générique quand on accepte n'importe quelle collection :
public static <T> int taille(Collection<T> c) {
return c.size();
}
// Accepte List, Set, Queue — ou toute autre implémentation
taille(new ArrayList<>());
taille(new HashSet<>());
Collections — la boîte à outils
Collections (avec un s) est une classe finale remplie de méthodes statiques qui opèrent sur des Collection existantes : tri, recherche, inversion, vues immuables, synchronisation.
public final class Collections {
public static <T> void sort(List<T> list);
public static <T> List<T> unmodifiableList(List<? extends T> list);
public static <T> List<T> synchronizedList(List<T> list);
public static <T> void reverse(List<?> list);
public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key);
// ...
}
Exemples d'usage de Collections
Trier une liste
List<Integer> nombres = new ArrayList<>(List.of(3, 1, 4, 1, 5, 9, 2, 6));
Collections.sort(nombres);
// [1, 1, 2, 3, 4, 5, 6, 9]
Inverser
Collections.reverse(nombres);
// [9, 6, 5, 4, 3, 2, 1, 1]
Min, max
int min = Collections.min(nombres); // 1
int max = Collections.max(nombres); // 9
Liste non modifiable
List<String> originale = new ArrayList<>(List.of("a", "b", "c"));
List<String> readOnly = Collections.unmodifiableList(originale);
readOnly.add("d"); // ❌ UnsupportedOperationException
Liste synchronisée
List<String> safe = Collections.synchronizedList(new ArrayList<>());
// Toutes les méthodes sont thread-safe individuellement
Collections vides / singleton
List<String> vide = Collections.emptyList();
List<String> un = Collections.singletonList("seul");
Set<Integer> unSet = Collections.singleton(42);
Recherche dichotomique
List<Integer> trie = List.of(1, 3, 5, 7, 9);
int index = Collections.binarySearch(trie, 5); // 2
Tableau récapitulatif
Collection | Collections | |
|---|---|---|
| Nature | Interface | Classe finale |
| Rôle | Décrire ce qu'est une collection | Fournir des outils pour les collections |
| Utilisation typique | Type de paramètre ou de retour | Méthodes statiques |
| Instanciable ? | Non (via ArrayList, etc.) | Non (constructeur privé) |
| Exemple | Collection<String> c = ...; | Collections.sort(list); |
L'évolution moderne
Depuis Java 8, les fonctions les plus utiles de Collections ont des équivalents directement sur les interfaces :
Collections.sort(list)→list.sort(null)Collections.reverse(list)→ pas d'équivalent direct, maislist.reversed()depuis Java 21Collections.unmodifiableList(list)→List.copyOf(list)(Java 10+)Collections.emptyList()→List.of()(Java 9+)
Dans du code Java moderne, vous utiliserez Collections principalement pour les vues synchronisées et quelques cas particuliers.
Pièges fréquents
Collections.sort()modifie la liste sur place — elle doit donc être modifiable.List.of(...)est immuable et lèveUnsupportedOperationException.Collections.synchronizedListne synchronise pas l'itération — enveloppez lefordans unsynchronized(list) { ... }.Collections.unmodifiableListest une vue : modifier la liste d'origine affecte la vue.List.copyOffait une copie profonde de la référence.
En bref : Collection = la donnée, Collections = les outils. La différence d'un s change totalement le rôle.