25. L’API List
Table des matières
- 25.1 Caractéristiques des List
- 25.2 Créer des List (Constructeurs)
- 25.3 Méthodes Factory
- 25.4 Opérations Principales de List
- 25.5 contains, equals et hashCode
- 25.6 Itérer à Travers une List
- 25.7 La Méthode subList
- 25.8 Tableau Résumé des Opérations Importantes
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)etset(int,E). - Autorisent les doublons —
Listn’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) |