À l'issue de ce chapitre, l'étudiant sera capable de :
List<T>Dictionary<TKey, TValue> pour stocker des paires clé-valeurHashSet<T> pour gérer des ensembles de valeurs uniquesQueue<T>Stack<T>Les tableaux vus au chapitre 1 disposent déjà de certaines méthodes utiles :
Cependant, ils conservent des limites importantes :
Add(), Remove(), Insert()Les collections génériques résolvent ces limites en offrant des structures dynamiques, typées et riches en fonctionnalités.
Toutes les collections génériques se trouvent dans l'espace de noms :
| Collection | Description | Analogue |
|---|---|---|
List<T> | Liste dynamique indexée | Tableau redimensionnable |
Dictionary<K,V> | Paires clé-valeur | Table de hachage |
HashSet<T> | Ensemble de valeurs uniques | Ensemble mathématique |
Queue<T> | File d'attente (FIFO) | File au guichet |
Stack<T> | Pile (LIFO) | Pile d'assiettes |
List<T> est une collection ordonnée, dynamique et indexée. Elle grandit automatiquement selon les besoins.
| Méthode | Description |
|---|---|
Add(T) | Ajoute un élément à la fin |
Insert(index, T) | Insère à une position donnée |
Remove(T) | Supprime la première occurrence |
RemoveAt(index) | Supprime à l'indice donné |
Contains(T) | Vérifie la présence d'un élément |
IndexOf(T) | Retourne l'indice (ou -1) |
Sort() | Trie la liste |
Reverse() | Inverse l'ordre |
Clear() | Vide la liste |
Count | Nombre d'éléments (propriété) |
Écrivez un programme qui :
List<int> contenant les notes : 14, 8, 17, 11, 19, 6, 13Déterminez la sortie de ce code :
Étapes : {5,10,15,20} → Insert(2,12): {5,10,12,15,20} → RemoveAt(0): {10,12,15,20} → Add(25): {10,12,15,20,25} → Remove(20): {10,12,15,25}
Sortie : 10, 12, 15, 25
Dictionary<TKey, TValue> stocke des paires clé-valeur. Chaque clé est unique et permet un accès rapide à la valeur associée.
| Méthode / Propriété | Description |
|---|---|
Add(key, value) | Ajoute une paire (exception si clé existe) |
[key] = value | Ajoute ou met à jour |
Remove(key) | Supprime la paire par clé |
ContainsKey(key) | Vérifie si la clé existe |
ContainsValue(value) | Vérifie si la valeur existe |
TryGetValue(key, out val) | Lecture sécurisée |
Count | Nombre de paires |
Keys | Collection des clés |
Values | Collection des valeurs |
Écrivez un programme qui :
{ "pomme", "banane", "pomme", "orange", "banane", "pomme" }Dictionary<string, int> pour compter les occurrences de chaque motDéterminez la sortie de ce code :
Sortie : 3 puis False puis 20
Explication : après Remove("a") et ajout de "d", il reste 3 paires. La clé "a" n'existe plus. "b" vaut 20.
HashSet<T> est un ensemble de valeurs uniques et non ordonnées. Il ignore automatiquement les doublons et offre des recherches très rapides.
[0])| Méthode | Description |
|---|---|
Add(T) | Ajoute (retourne false si doublon) |
Remove(T) | Supprime un élément |
Contains(T) | Vérifie la présence |
UnionWith(autre) | Union : A ∪ B |
IntersectWith(autre) | Intersection : A ∩ B |
ExceptWith(autre) | Différence : A \ B |
IsSubsetOf(autre) | Vérifie si sous-ensemble |
Soient deux groupes d'étudiants :
Groupe A : { "Ali", "Sara", "Omar", "Fatma" }
Groupe B : { "Sara", "Khaled", "Fatma", "Imen" }
Écrivez un programme qui affiche :
Sortie : False → True → 3 → False
Add(20) retourne false (doublon), Add(40) retourne true, après Remove(10) il reste {20,30,40}.
Queue<T> est une file d'attente qui suit le principe FIFO (First In, First Out) : le premier élément ajouté est le premier retiré.
Enqueue (ajouter) → [ A | B | C | D ] → Dequeue (retirer)
Analogie : une file d'attente au guichet. Le premier arrivé est le premier servi.
| Méthode | Description |
|---|---|
Enqueue(T) | Ajoute à la fin de la file |
Dequeue() | Retire et retourne le premier élément |
Peek() | Consulte le premier sans le retirer |
Contains(T) | Vérifie la présence |
Count | Nombre d'éléments |
Écrivez un programme qui simule un guichet de banque :
Queue<string> avec 5 clients : "Client1" à "Client5"File: [10,20,30] → Dequeue()=10 → [20,30] → Enqueue(40) → [20,30,40] → Peek()=20 → Dequeue()=20 → [30,40] → Count=2
Sortie : 10 → 20 → 20 → 2
Stack<T> est une pile qui suit le principe LIFO (Last In, First Out) : le dernier élément ajouté est le premier retiré.
Push (empiler) → | D |
| C |
| B |
| A | → Pop retire D (le sommet)
Analogie : une pile d'assiettes. On prend toujours celle du dessus.
| Méthode | Description |
|---|---|
Push(T) | Empile un élément (au sommet) |
Pop() | Dépile et retourne le sommet |
Peek() | Consulte le sommet sans dépiler |
Contains(T) | Vérifie la présence |
Count | Nombre d'éléments |
Cas d'usage courants de Stack<T> : historique de navigation (bouton retour), fonctionnalité Annuler/Rétablir (Undo/Redo), évaluation d'expressions mathématiques, vérification de parenthèses.
Écrivez un programme qui utilise un Stack<char> pour vérifier si une chaîne contient des parenthèses correctement équilibrées.
Exemples :
"((a+b)*(c-d))" → Équilibré"(a+b))" → Non équilibré"((a+b)" → Non équilibréAlgorithme : Parcourir chaque caractère. Si (, empiler. Si ), dépiler. À la fin, la pile doit être vide.
Pile: [10,20,30] → Pop()=30 → [10,20] → Push(40,50) → [10,20,40,50] → Peek()=50 → Pop()=50 → [10,20,40] → Count=3
Sortie : 30 → 50 → 50 → 3
| Collection | Accès | Ordre | Doublons | Cas d'usage |
|---|---|---|---|---|
List<T> |
Par indice | Maintenu | Oui | Liste ordonnée, accès aléatoire |
Dictionary<K,V> |
Par clé | Non garanti | Clés uniques | Associations clé→valeur |
HashSet<T> |
Aucun | Non garanti | Non | Valeurs uniques, opérations ensemblistes |
Queue<T> |
Premier (FIFO) | FIFO | Oui | File d'attente, traitement séquentiel |
Stack<T> |
Dernier (LIFO) | LIFO | Oui | Annuler, historique, récursion |
Besoin d'une liste ordonnée avec accès par indice ? → List<T>
Besoin d'associer des clés à des valeurs ? → Dictionary<K,V>
Besoin de garantir l'unicité des éléments ? → HashSet<T>
Traitement dans l'ordre d'arrivée (FIFO) ? → Queue<T>
Traitement en ordre inverse (LIFO) ? → Stack<T>
| Opération | List | Dictionary | HashSet | Queue | Stack |
|---|---|---|---|---|---|
| Ajout | O(1)* | O(1) | O(1) | O(1) | O(1) |
| Recherche | O(n) | O(1) | O(1) | O(n) | O(n) |
| Suppression | O(n) | O(1) | O(1) | O(1) | O(1) |
| Accès indice | O(1) | — | — | — | — |
* O(1) amorti, O(n) si redimensionnement nécessaire
Pour chaque situation, indiquez la collection la plus adaptée et justifiez :
Écrivez un programme de gestion d'un restaurant :
Dictionary<string, double> pour le menu (plat → prix)Queue<string> pour les commandes en attenteDictionary<string, double> — accès par clé (nom)Stack<string> — LIFO pour le retourHashSet<string> — unicité garantieQueue<string> — FIFO, premier arrivé premier serviList<string> — ordonnée, modifiable, doublons possiblesList<T> : tableau dynamiqueDictionary<K,V> : paires clé-valeurHashSet<T> : valeurs uniquesQueue<T>Stack<T>System.Collections.Generic