JEP 431, Sequenced Collections

Contexte

L’objectif est d’avoir des interfaces qui permettent d’avoir des collections gérant l’ordonnancement.

Actuellement, des méthodes existent sur certaines classes mais n’ont pas forcément le même nom. Cela ne permet pas de manipuler simplement ces objets.

          | Premier élément   | Dernier élément
#---------+-------------------+-----------------------------
List 	  | list.get(0)       | list.get(list.size() - 1)
Deque 	  | deque.getFirst()  | deque.getLast()
SortedSet | sortedSet.first() | sortedSet.last()
#---------+-------------------+-----------------------------

Principe

Pour atteindre cet objectif, une API unifiée a été mis en place. Pour cela, l’interface SequencedCollection a été introduite.

interface SequencedCollection<E> extends Collection<E> {
    // new method
    SequencedCollection<E> reversed();
    // methods promoted from Deque
    void addFirst(E);
    void addLast(E);
    E getFirst();
    E getLast();
    E removeFirst();
    E removeLast();
}

On peut remarquer que la manière de récupérer le premier et le dernier est normalisée par les méthodes getFirst() et getLast().

Il est intéressant de noter la présence de la méthode reversed(). Elle permet d’obtenir simplement la collection dans l’ordre inversé.

Au niveau des ensembles Set, nous avons ensuite l’interface SequencedSet.

interface SequencedSet<E> extends Set<E>, SequencedCollection<E> {
    SequencedSet<E> reversed();    // surcharge covariante
}

avertissement Il est à noter la surcharge de la méthode reverse() qui renvoie SequencedSet au lieu d’un simple SequencedCollection.

pour finir, nous avons une interface pour les maps avec l’interface SequencedMap :

interface SequencedMap<K,V> extends Map<K,V> {
    // new methods
    SequencedMap<K,V> reversed();
    SequencedSet<K> sequencedKeySet();
    SequencedCollection<V> sequencedValues();
    SequencedSet<Entry<K,V>> sequencedEntrySet();
    V putFirst(K, V);
    V putLast(K, V);
    // methods promoted from NavigableMap
    Entry<K, V> firstEntry();
    Entry<K, V> lastEntry();
    Entry<K, V> pollFirstEntry();
    Entry<K, V> pollLastEntry();
}

Implémentation

De plus, les nouvelles interfaces sont intégrées dans la hiérarchie de classes et d’interfaces existantes.

SequencedCollectionDiagram20220216

Par exemple, nous avons :

  • List réalise l’interface SequencedCollection

  • Deque réalise l’interface SequencedCollection en plus de l’interface Queue

  • SortedSet et LinkedHashSet réalisent l’interface SequencedSet au lieu de directement Set

  • SortedMap et LinkedHashMap réalisent l’interface Sequencedmap au lieu de directement Map

Risques

Il est à noter qu’une analyse de risque a été faite. Lors de cette phase, des problèmes de compilation ont été identifiées sur 31 artefacts sur le corpus entier de Maven Central (soit un total de 37 377 artefacts). Cela représente seulement 0.08%. (Lien vers la page de l’analyse est en référence, plus bas)

astuceLà encore, le compilateur est notre allié.