📚 Le cours : les structures de données prêtes à l'emploi
Un tableau a une taille fixe et peu d'opérations. Le paquetage java.util fournit des collections : des structures de données déjà écrites, qui grandissent à la demande et offrent des méthodes pour ajouter, chercher, supprimer.
| Collection | Ce qu'elle fait | Quand la choisir |
ArrayList<T> | liste ordonnée, accès par indice | le choix par défaut pour une suite d'éléments |
HashMap<K, V> | association clé → valeur, recherche très rapide | retrouver une valeur à partir d'une clé (nom → note) |
HashSet<T> | ensemble sans doublon | tester l'appartenance, supprimer les doublons |
TreeMap, TreeSet | comme HashMap / HashSet, mais triés | parcourir dans l'ordre des clés |
ArrayDeque<T> | pile (LIFO) ou file (FIFO) | empiler / défiler |
Les génériques : le type entre chevrons
ArrayList<String> ne contient que des String : le compilateur refuse d'y ajouter autre chose et dispense de convertir à la lecture. Les chevrons n'acceptent que des classes, pas les types primitifs : on écrit ArrayList<Integer> (et non ArrayList<int>). Java convertit automatiquement int ⇄ Integer (*boxing*), de même pour double ⇄ Double, char ⇄ Character.
Parcourir, trier, modifier une ArrayList
On parcourt avec un for-each ou avec un indice (liste.get(i), de 0 à liste.size() - 1). Collections.sort(liste) trie en place ; set(i, valeur) remplace un élément.
import java.util.ArrayList;
import java.util.Collections;
public class Parcours {
public static void main(String[] args) {
ArrayList<Integer> nombres = new ArrayList<>();
nombres.add(5);
nombres.add(2);
nombres.add(9);
Collections.sort(nombres);
int somme = 0;
for (int n : nombres) {
somme += n;
}
System.out.println(nombres + " somme = " + somme);
nombres.set(0, 100);
System.out.println(nombres);
}
}
Affichage[2, 5, 9] somme = 16
[100, 5, 9]
Supprimer des éléments en filtrant
Modifier une liste pendant un for-each lève une ConcurrentModificationException. Pour supprimer selon un critère, utilise removeIf avec une condition écrite sous forme de lambda (n -> n % 2 == 0 se lit « pour chaque n, n pair »).
import java.util.ArrayList;
public class Filtre {
public static void main(String[] args) {
ArrayList<Integer> nombres = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
nombres.add(i);
}
nombres.removeIf(n -> n % 2 == 0);
System.out.println(nombres);
}
}
Compter avec une Map
Une Map est idéale pour compter : la clé est l'élément, la valeur est son nombre d'occurrences. getOrDefault(c, 0) + 1 évite de tester si la clé existe. Un HashMap ne garantit aucun ordre de parcours ; un TreeMap parcourt les clés dans l'ordre croissant.
import java.util.Map;
import java.util.TreeMap;
public class Frequences {
public static void main(String[] args) {
String texte = "abracadabra";
TreeMap<Character, Integer> freq = new TreeMap<>();
for (char c : texte.toCharArray()) {
freq.put(c, freq.getOrDefault(c, 0) + 1);
}
for (Map.Entry<Character, Integer> e : freq.entrySet()) {
System.out.println(e.getKey() + " : " + e.getValue());
}
}
}
Affichagea : 5
b : 2
c : 1
d : 1
r : 2
C'est l'équivalent du dictionnaire Python : dans les deux cas, une table de hachage rend la recherche d'une clé très rapide.
Supprimer les doublons avec un Set
Un Set ignore l'ajout d'un élément déjà présent. new TreeSet<>(collection) construit en plus un ensemble trié.
import java.util.Arrays;
import java.util.TreeSet;
public class Doublons {
public static void main(String[] args) {
Integer[] valeurs = {4, 8, 4, 15, 8, 16};
TreeSet<Integer> uniques = new TreeSet<>(Arrays.asList(valeurs));
System.out.println(uniques);
System.out.println(uniques.contains(15));
}
}
Affichage[4, 8, 15, 16]
true
Tableau ou ArrayList ?
Un tableau (int[]) est plus rapide et accepte les types primitifs, mais sa taille est figée. Une ArrayList s'agrandit seule (elle remplace son tableau interne par un plus grand quand il est plein, comme avec realloc en C) et fournit add, remove, contains, mais ne contient que des objets.