W3docs

Interface Collection en Java

L'interface Collection racine en Java et le contrat hérité par chaque liste, ensemble et file d'attente.

java.util.Collection<E> est la racine de la partie du framework qui contient des éléments individuels — chaque List, Set, Queue et Deque l'implémente (la seule famille qui ne le fait pas est Map, dont les éléments sont des entrées, pas des valeurs uniques). Tout ce que vous pouvez faire « quel que soit le groupe » — ajouter, supprimer, demander contains, itérer, compter, convertir en tableau, streamer — est déclaré ici. Ce chapitre est le contrat : les méthodes sur lesquelles vous pouvez compter pour n'importe quelle collection, les quelques-unes qui peuvent lever des exceptions, et le modèle d'itération que chaque implémentation hérite.

La hiérarchie en un coup d'œil

Iterable<E>
  └── Collection<E>
        ├── List<E>           — ordered, indexed, duplicates allowed
        ├── Set<E>            — no duplicates
        │     └── SortedSet<E> → NavigableSet<E>
        └── Queue<E>          — "next in line"
              └── Deque<E>    — double-ended queue

Collection étend Iterable<E>, c'est pourquoi chaque collection fonctionne avec la boucle for-each. Les deux spécialisations de CollectionSet et Queue — affinent le contrat ; Map est sa propre racine.

Méthodes de base disponibles dans toute collection

Voici l'ensemble complet des méthodes d'instance sur Collection, regroupées par objectif. Mémorisez les catégories plutôt que la liste — une fois que vous savez qu'il existe une méthode appelée removeIf, vous pouvez la retrouver.

Taille et vacuité

  • int size() — nombre d'éléments.
  • boolean isEmpty()size() == 0 mais souvent plus rapide.

Ajout

  • boolean add(E e) — ajoute un élément. Retourne true si la collection a changé. (Un Set retourne false pour un doublon.)
  • boolean addAll(Collection<? extends E> c) — ajoute chaque élément de c.

Suppression

  • boolean remove(Object o) — supprime une occurrence de o.
  • boolean removeAll(Collection<?> c) — supprime chaque élément qui apparaît dans c.
  • boolean retainAll(Collection<?> c) — conserve uniquement les éléments présents dans c (intersection).
  • boolean removeIf(Predicate<? super E> filter) — supprime chaque élément correspondant au prédicat. La façon la plus propre de filtrer en place.
  • void clear() — vide la collection.

Interrogation

  • boolean contains(Object o) — test d'appartenance.
  • boolean containsAll(Collection<?> c) — test de sous-ensemble.

Itération et vues groupées

  • Iterator<E> iterator() — l'itérateur sous-jacent ; ce qu'utilise for-each.
  • Stream<E> stream() / parallelStream() — ouvre un Stream sur les éléments.
  • void forEach(Consumer<? super E> action) — héritée de Iterable. La forme d'itération fonctionnelle.

Conversion en tableau

  • Object[] toArray()
  • <T> T[] toArray(T[] a) et le plus récent <T> T[] toArray(IntFunction<T[]> generator) (Java 11+) — tableau typé.

C'est l'intégralité de l'interface. Chaque liste, ensemble et file d'attente que vous rencontrerez dans cette partie n'est qu'une implémentation différente de ces méthodes plus quelques-unes qui lui sont propres.

Égalité et equals / hashCode

Collection.equals(Object) n'est pas défini à la racine — chaque sous-interface spécifie ce que l'égalité signifie pour elle. List exige les mêmes éléments dans le même ordre ; Set exige les mêmes éléments indépendamment de l'ordre ; Queue ne définit pas equals du tout (une file LinkedList et une file ArrayDeque ayant le même contenu ne sont pas égales car la comparaison revient à l'identité d'objet). Ne comparez pas des collections entre familles différentes en attendant la symétrie.

Les éléments stockés dans une Collection doivent avoir des equals / hashCode cohérents si vous voulez que contains, remove et (pour les collections basées sur le hachage) les recherches fonctionnent correctement. Nous avons couvert le contrat dans le chapitre equals et hashCode — c'est le prérequis pour utiliser Set et Map avec vos propres classes.

Opérations optionnelles

Certaines collections sont non modifiables — List.of(1,2,3), Collections.unmodifiableList(list), les vues retournées par Map.keySet() sur certaines implémentations, etc. Elles implémentent toujours Collection, mais appeler add, remove, clear, ou toute méthode de mutation lève UnsupportedOperationException. La Javadoc appelle celles-ci des « opérations optionnelles ». C'est ce qui se rapproche le plus, en Java, d'une exclusion à l'exécution de parties d'une interface ; le prix est que le compilateur ne peut pas détecter l'erreur — vous le découvrez à la première exception levée.

Une règle sûre : si vous n'avez pas construit la collection, traitez-la comme potentiellement non modifiable. Si vous avez besoin d'une copie mutable, faites d'abord new ArrayList<>(received).

Itération : trois formes, un mécanisme sous-jacent

Chaque collection prend en charge trois styles d'itération, et tous trois finissent par appeler iterator() :

Collection<String> names = List.of("Ada", "Linus", "Grace");

// 1. for-each — the everyday form
for (String n : names) System.out.println(n);

// 2. forEach with a lambda — declarative
names.forEach(System.out::println);

// 3. Iterator — when you need to remove during iteration
Iterator<String> it = names.iterator();
while (it.hasNext()) {
  String s = it.next();
  if (s.startsWith("L")) it.remove();   // safe; for-each can't do this
}

Pourquoi les formes 1 et 3 ont encore leur importance : la boucle for-each ne peut pas modifier la collection sous-jacente sans lever ConcurrentModificationException. Lorsque vous devez supprimer pendant l'itération, vous utilisez l'Iterator explicite. Le chapitre Iterators plus loin dans cette partie couvre le protocole en détail.

Algèbre d'ensembles avec les opérations groupées

Les opérations groupées transforment une collection en calculatrice d'algèbre d'ensembles (indépendamment du fait qu'il s'agisse d'un Set — elles fonctionnent aussi sur List) :

Collection<Integer> a = new ArrayList<>(List.of(1, 2, 3, 4));
Collection<Integer> b = List.of(3, 4, 5);

a.addAll(b);                 // union (multiset)
a.retainAll(List.of(3, 4));  // intersection
a.removeAll(List.of(3));     // difference

Ce sont les façons sûres et sans dépendances d'exprimer « ne garder que les éléments présents dans b » sans écrire de boucle. Elles modifient le récepteur — si vous avez besoin d'un résultat immuable, copiez d'abord.

Un exemple complet : toutes les méthodes côte à côte

Le programme ci-dessous exerce chaque catégorie de méthode de Collection sur le même ArrayList, afin que vous puissiez les voir en un seul endroit et observer le contrat en action.

java— editable, runs on the server

Deux points à noter à partir de la sortie :

  1. remove("red") n'a supprimé que la première occurrence — c'est le contrat sur Collection. Pour supprimer chaque correspondance, utilisez removeIf (vous l'avez vu ensuite, supprimant chaque mot de plus de quatre caractères).
  2. L'UnsupportedOperationException de frozen.add("d") est la règle des « opérations optionnelles » en action. frozen implémente Collection, donc l'appel compile. L'implémentation a choisi de ne pas le supporter, et vous le découvrez à l'exécution.

Et maintenant

Collection est le contrat abstrait. Le premier raffinement concret que vous rencontrerez est celui qui ajoute l'ordre et l'indexation — l'interface List. C'est là qu'interviennent l'accès indexé, les sous-listes et les opérations préservant l'ordre.

Pratique

Pratique
Vous avez une `Collection<String>` et souhaitez supprimer chaque élément dont la longueur est supérieure à quatre. Quelle approche est la méthode idiomatique en une seule instruction ?
Vous avez une `Collection<String>` et souhaitez supprimer chaque élément dont la longueur est supérieure à quatre. Quelle approche est la méthode idiomatique en une seule instruction ?
Was this page helpful?