Skip to content

25. L’API List

Table des matières


Dans le Collections Framework, une List représente une collection ordonnée, basée sur des indices, autorisant les doublons.

L’interface List étend Collection et est implémentée par :

List
├── ArrayList (Tableau redimensionnable — accès aléatoire rapide, insertions/suppressions plus lentes au milieu)
├── LinkedList (Liste doublement chaînée — insertions/suppressions rapides, accès aléatoire plus lent)
└── Vector (Liste synchronisée legacy — rarement utilisée aujourd’hui)

Note

Vector est legacy et synchronisé — à éviter sauf si explicitement requis.

25.1 Caractéristiques des List

  • Ordonnées — les éléments préservent l’ordre d’insertion.
  • Indexées — accessibles via get(int) et set(int,E).
  • Autorisent les doublons — List n’impose pas l’unicité.
  • Peuvent contenir null — sauf si l’on utilise des implémentations spéciales.

25.2 Créer des List (Constructeurs)

25.2.1 Constructeurs de ArrayList

List<String> a1 = new ArrayList<>();
List<String> a2 = new ArrayList<>(50); // capacité initiale
List<String> a3 = new ArrayList<>(List.of("A", "B"));

Note

La capacité initiale n’est pas une taille. Elle décide seulement combien d’éléments le tableau interne peut contenir avant redimensionnement.

25.2.2 Constructeurs de LinkedList

List<String> l1 = new LinkedList<>();
List<String> l2 = new LinkedList<>(List.of("A", "B"));

Note

LinkedList implémente aussi Deque.


25.3 Méthodes Factory

25.3.1 List.of() (immuable)

List<String> list1 = List.of("A", "B", "C");
list1.add("X"); // ❌ UnsupportedOperationException
list1.set(0, "Z"); // ❌ UnsupportedOperationException

Note

Toutes les listes List.of() : - rejettent les null - sont immuables - lèvent UOE lors d’une modification structurelle

25.3.2 List.copyOf() (copie immuable)

List<String> src = new ArrayList<>();
src.add("Hello");

List<String> copy = List.copyOf(src); // instantané immuable

25.3.3 Arrays.asList() (liste à taille fixe)

String[] arr = {"A", "B"};
List<String> list = Arrays.asList(arr);

list.set(0, "Z"); // OK
list.add("X"); // ❌ UOE — la taille est fixe

Note

La liste est adossée au tableau : modifier l’un affecte l’autre.


25.4 Opérations Principales de List

25.4.1 Ajouter des Éléments

list.add("A");
list.add(1, "B"); // insère à l’index
list.addAll(otherList);
list.addAll(2, otherList);

25.4.2 Accéder aux Éléments

String x = list.get(0);
list.set(1, "NewValue");

Note

get() lève IndexOutOfBoundsException pour des index invalides.

Si vous essayez de mettre à jour un élément dans une List vide, même à l’index 0, vous obtenez une IndexOutOfBoundsException

List<Integer> list = new ArrayList<Integer>();
list.add(3);
list.add(5);
System.out.println(list.toString());
list.clear();
list.set(0, 2);

Sortie

[3, 5]
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0

Warning

Appeler get/set avec un index invalide lève IndexOutOfBoundsException

25.4.3 Supprimer des Éléments

list.remove(0); // remove(int index) — supprime par index ; remove(Object) — supprime le premier élément égal
list.remove("A"); // supprime la première occurrence
list.removeIf(s -> s.startsWith("X"));
list.clear();

25.4.4 Comportements et Caractéristiques Importants

Opération Comportement Exception(s)
add(E) ajoute toujours à la fin
add(int,E) décale les éléments vers la droite IndexOutOfBoundsException
get(int) temps constant pour ArrayList, linéaire pour LinkedList IndexOutOfBoundsException
set(int,E) remplace l’élément IndexOutOfBoundsException
remove(int) décale les éléments vers la gauche IndexOutOfBoundsException
remove(Object) supprime le premier élément égal

25.5 contains(), equals() et hashCode()

25.5.1 contains()

La Méthode contains() utilise .equals() sur les éléments.

25.5.2 Égalité des List

List.equals() effectue une comparaison élément par élément dans l’ordre.

List<String> a = List.of("A", "B");
List<String> b = List.of("A", "B");

System.out.println(a.equals(b)); // true

Note

  • L’ordre compte.
  • Le type de liste ne compte PAS.

25.5.3 hashCode()

Calculé sur la base du contenu.


25.6 Itérer à Travers une List

25.6.1 Boucle For Classique

for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}

25.6.2 Boucle For Améliorée

for (String s : list) {
    System.out.println(s);
}

25.6.3 Iterator & ListIterator

Iterator<String> it = list.iterator();
while (it.hasNext()) { System.out.println(it.next()); }

ListIterator<String> lit = list.listIterator();
while (lit.hasNext()) {
    if (lit.next().equals("A")) lit.set("Z");
}

Warning

Tous les itérateurs standard de List sont fail-fast : une modification structurelle en dehors de l’itérateur cause ConcurrentModificationException.

Note

Seul ListIterator supporte la traversée bidirectionnelle et la modification.


25.7 La Méthode subList()

subList() crée une vue d’une portion de la liste, pas une copie. Modifier l’une des deux peut modifier l’autre.

25.7.1 Syntaxe

List<E> subList(int fromIndex, int toIndex);

25.7.2 Règles

Règle Explication
fromIndex inclusif l’élément à fromIndex est inclus
toIndex exclusif l’élément à toIndex n’est PAS inclus
La vue est adossée à la liste originale modifier l’une modifie l’autre
Modification structurelle du parent invalide la subList → ConcurrentModificationException

25.7.3 Exemples

List<String> list = new ArrayList<>(List.of("A", "B", "C", "D"));
List<String> view = list.subList(1, 3);
// view = ["B", "C"]

view.set(0, "X");
// list = ["A", "X", "C", "D"]
// view = ["X", "C"]

25.7.4 Modifier la liste parent invalide la vue

List<String> list = new ArrayList<>(List.of("A","B","C","D"));
List<String> view = list.subList(1, 3);

list.add("E"); // modification structurelle de la liste parent

view.get(0); // ❌ ConcurrentModificationException

25.7.5 Modifier la subList modifie le parent

view.remove(1);
// supprime "C" à la fois de la view et de la liste parent

25.7.6 Vider la subList vide une partie de la liste parent

view.clear();
// supprime les index 1 et 2 du parent

25.7.7 Pièges Courants

  • Supposer que subList est indépendante : c’est une vue, pas une copie
  • Supposer que subList permet le redimensionnement : fonctionne uniquement sur des listes parent modifiables
  • Oublier que les modifications du parent invalident la vue entraînant ConcurrentModificationException
  • Attentes d’index incorrectes : l’index de fin est exclusif

25.8 Tableau Résumé des Opérations Importantes

Opération ArrayList LinkedList List Immuables
add(E) rapide rapide ❌ non supporté
add(index,E) lent (shift) rapide
get(index) rapide lent rapide
remove(index) lent lent (sauf si suppression du premier/dernier)
remove(Object) plus lent plus lent
set(index,E) rapide lent
iterator() rapide rapide rapide
listIterator() rapide rapide rapide
contains(Object) O(n) O(n) O(n)