29. Collections Séquencées & Map Séquencées
Table des matières
- 29.1 Motivation et Contexte
- 29.2 Interface SequencedCollection
- 29.3 Interface SequencedMap
- 29.4 Relation avec les API Existantes
- 29.5 Pièges Courants
- 29.6 Résumé
Java 21 introduit les Collections Séquencées et les Map Séquencées afin d’unifier et de formaliser l’accès aux éléments en fonction de leur ordre d’apparition.
Cet ajout résout des incohérences de longue date entre listes, sets, queues, deques et map, en fournissant une API commune pour travailler avec le premier et le dernier élément, ainsi qu’avec des vues inversées.
29.1 Motivation et Contexte
Avant Java 21, les collections ordonnées (telles que List, LinkedHashSet, Deque ou LinkedHashMap) exposaient les opérations liées à l’ordre via des méthodes différentes ou, dans certains cas, pas du tout.
Les développeurs devaient s’appuyer sur des API spécifiques à l’implémentation ou sur des contournements indirects.
Les interfaces séquencées introduisent un contrat cohérent pour toutes les collections et map ordonnées, rendant les opérations basées sur l’ordre explicites, sûres et uniformes.
29.2 Interface SequencedCollection
SequencedCollection<E> est une nouvelle interface qui étend Collection<E> et représente des collections avec un ordre d’apparition bien défini.
Elle est implémentée par List, Deque et LinkedHashSet (TreeSet est ordonné mais n’implémente pas directement SequencedCollection).
29.2.1 Méthodes Principales de SequencedCollection
L’interface définit des méthodes pour accéder et manipuler les éléments aux deux extrémités de la collection.
| Méthode | Description |
|---|---|
E getFirst() |
Retourne le premier élément |
E getLast() |
Retourne le dernier élément |
void addFirst(E e) |
Insère un élément au début |
void addLast(E e) |
Insère un élément à la fin |
E removeFirst() |
Supprime et retourne le premier élément |
E removeLast() |
Supprime et retourne le dernier élément |
SequencedCollection<E> reversed() |
Retourne une vue inversée |
29.2.2 Implémentations de SequencedCollection
Les types standards suivants implémentent SequencedCollection :
| Type | Notes |
|---|---|
| List | Ordonnée par index |
| Deque | File à double extrémité |
| LinkedHashSet | Maintient l’ordre d’insertion |
29.2.3 Vues Inversées
L’appel à reversed() ne crée pas de copie.
Il retourne une vue live de la même collection avec l’ordre inversé.
List<Integer> list = new ArrayList<>(List.of(1, 2, 3));
SequencedCollection<Integer> rev = list.reversed();
rev.removeFirst(); // supprime 3
System.out.println(list); // [1, 2]
Note
Les vues inversées partagent la même collection sous-jacente. Les modifications structurelles dans l’une ou l’autre vue affectent l’autre : modifier soit la collection originale soit la vue inversée a un effet sur les deux.
29.3 Interface SequencedMap
SequencedMap<K,V> étend Map<K,V> et représente des map avec un ordre d’apparition des entrées bien défini.
Elle standardise des opérations qui n’existaient auparavant que dans des implémentations spécifiques comme LinkedHashMap.
29.3.1 Méthodes Principales de SequencedMap
| Méthode | Description |
|---|---|
Entry<K,V> firstEntry() |
Première entrée de la map |
Entry<K,V> lastEntry() |
Dernière entrée de la map |
Entry<K,V> pollFirstEntry() |
Supprime et retourne la première entrée, ou null si vide |
Entry<K,V> pollLastEntry() |
Supprime et retourne la dernière entrée, ou null si vide |
SequencedMap<K,V> reversed() |
Vue inversée de la map |
29.3.2 Implémentations de SequencedMap
Actuellement, la principale implémentation standard est :
| Type | Ordonnancement |
|---|---|
LinkedHashMap |
Ordre d’insertion (ou ordre d’accès si configuré) |
Note
LinkedHashMap peut réordonner les entrées lors de la lecture si elle est construite avec accessOrder=true.
Dans ce cas, « première » et « dernière » reflètent l’ordre d’accès le plus récent.
29.3.3 Map Inversées
Comme pour les collections, reversed() sur une map séquencée retourne une vue, et non une copie.
SequencedMap<String, Integer> map =
new LinkedHashMap<>(Map.of("A", 1, "B", 2, "C", 3));
SequencedMap<String, Integer> rev = map.reversed();
rev.pollFirstEntry(); // supprime C=3
System.out.println(map); // {A=1, B=2}
Note
Comme pour SequencedCollection, reversed() retourne une vue live — les mutations s’appliquent aux deux map.
29.4 Relation avec les API Existantes
Les interfaces séquencées ne remplacent pas les types de collections existants.
Elles se placent au-dessus d’eux dans la hiérarchie et unifient les comportements communs.
Toutes les collections ordonnées existantes bénéficient automatiquement de ces API sans casser la rétrocompatibilité.
29.4.1 Quels Types Built-in Sont Séquencés
Le tableau suivant résume si les types standards de collections sont ordonnés et s’ils implémentent les nouvelles interfaces Sequenced.
| Type | Ordonné ? | SequencedCollection ? | SequencedMap ? |
|---|---|---|---|
List |
✔ Oui | ✔ Oui | ✘ Non |
Deque |
✔ Oui | ✔ Oui | ✘ Non |
LinkedHashSet |
✔ Oui | ✔ Oui | ✘ Non |
TreeSet |
✔ Oui (trié) | ✘ Non* | ✘ Non |
HashSet |
✘ Non | ✘ Non | ✘ Non |
LinkedHashMap |
✔ Oui | ✘ Non | ✔ Oui |
HashMap |
✘ Non | ✘ Non | ✘ Non |
TreeMap |
✔ Oui (trié) | ✘ Non | ✘ Non |
Note
TreeSet est ordonné, mais implémente SortedSet/NavigableSet, pas SequencedCollection.
29.5 Pièges Courants
- Les interfaces séquencées définissent des vues, pas des copies
reversed()reflète les modifications de manière bidirectionnelle- Toutes les implémentations de Set ou de Map ne sont pas séquencées
- HashSet et HashMap n’implémentent pas les interfaces séquencées
- L’ordre n’est garanti que lorsqu’il est explicitement défini
- Supprimer des éléments via un iterator sur la vue inversée impacte immédiatement l’ordre original
29.6 Résumé
- Les interfaces séquencées formalisent l’ordre d’apparition
- Elles fournissent un accès first/last et l’inversion
- Elles fonctionnent via des vues live, pas des copies
- Elles unifient les API entre listes, deque, set et map