Leçon 8 - Collections

P2 - Structures de données

Maîtrisez les collections C# : List, Dictionary, HashSet et leurs utilisations pratiques.

Introduction aux collections

Les collections sont des structures de données qui permettent de stocker et manipuler des groupes d'objets de manière dynamique, contrairement aux tableaux qui ont une taille fixe.

List<T> - La liste générique

La liste est la collection la plus utilisée. Elle peut grandir et rétrécir dynamiquement.

C#
using System; using System.Collections.Generic; // Créer une liste de strings List<string> prenoms = new List<string>(); // Ajouter des éléments prenoms.Add("Alice"); prenoms.Add("Bob"); prenoms.Add("Charlie"); // Initialisation directe List<int> nombres = new List<int> { 1, 2, 3, 4, 5 }; // Accès aux éléments Console.WriteLine(prenoms[0]); // Alice Console.WriteLine($"Nombre d'éléments: {prenoms.Count}"); // 3

Opérations courantes sur les listes

C#
List<string> fruits = new List<string>(); // Ajouter des éléments fruits.Add("Pomme"); fruits.Add("Banane"); fruits.AddRange(new[] { "Orange", "Kiwi" }); // Ajouter plusieurs // Insérer à une position spécifique fruits.Insert(1, "Fraise"); // Insert à l'index 1 // Rechercher bool contientPomme = fruits.Contains("Pomme"); // true int indexOrange = fruits.IndexOf("Orange"); // Position d'Orange // Supprimer fruits.Remove("Banane"); // Supprimer par valeur fruits.RemoveAt(0); // Supprimer par index fruits.Clear(); // Vider la liste // Parcourir foreach (string fruit in fruits) { Console.WriteLine(fruit); }

Dictionary<TKey, TValue> - Le dictionnaire

Un dictionnaire stocke des paires clé-valeur, permettant un accès rapide aux données via une clé unique.

C#
// Dictionnaire pour stocker des âges Dictionary<string, int> ages = new Dictionary<string, int>(); // Ajouter des éléments ages.Add("Alice", 25); ages.Add("Bob", 30); ages["Charlie"] = 35; // Syntaxe alternative // Initialisation directe Dictionary<string, string> capitales = new Dictionary<string, string> { ["France"] = "Paris", ["Espagne"] = "Madrid", ["Italie"] = "Rome" }; // Accéder aux valeurs int ageAlice = ages["Alice"]; // 25 Console.WriteLine($"Alice a {ageAlice} ans");

Opérations sur les dictionnaires

C#
Dictionary<string, double> notes = new Dictionary<string, double>(); // Vérifier avant d'ajouter if (!notes.ContainsKey("Marie")) { notes["Marie"] = 16.5; } // Accès sécurisé avec TryGetValue if (notes.TryGetValue("Marie", out double noteMarie)) { Console.WriteLine($"Note de Marie: {noteMarie}"); } else { Console.WriteLine("Marie n'a pas de note"); } // Parcourir le dictionnaire foreach (KeyValuePair<string, double> kvp in notes) { Console.WriteLine($"{kvp.Key}: {kvp.Value}/20"); } // Ou plus simplement foreach (var (nom, note) in notes) { Console.WriteLine($"{nom}: {note}/20"); } // Supprimer notes.Remove("Marie"); // Accéder aux clés et valeurs foreach (string nom in notes.Keys) { Console.WriteLine($"Étudiant: {nom}"); } foreach (double note in notes.Values) { Console.WriteLine($"Note: {note}"); }

HashSet<T> - Ensemble sans doublons

Un HashSet stocke des éléments uniques sans ordre particulier, idéal pour éviter les doublons.

C#
// Créer un HashSet HashSet<string> couleurs = new HashSet<string>(); // Ajouter des éléments couleurs.Add("Rouge"); couleurs.Add("Vert"); couleurs.Add("Bleu"); couleurs.Add("Rouge"); // Doublon ignoré Console.WriteLine($"Nombre de couleurs uniques: {couleurs.Count}"); // 3 // Initialisation directe HashSet<int> numerosUniques = new HashSet<int> { 1, 2, 3, 2, 1 }; // {1, 2, 3} // Vérifier la présence if (couleurs.Contains("Rouge")) { Console.WriteLine("Rouge est présent"); } // Opérations ensemblistes HashSet<int> ensemble1 = new HashSet<int> { 1, 2, 3 }; HashSet<int> ensemble2 = new HashSet<int> { 3, 4, 5 }; // Union ensemble1.UnionWith(ensemble2); // {1, 2, 3, 4, 5} // Intersection HashSet<int> intersection = new HashSet<int>(ensemble1); intersection.IntersectWith(ensemble2); // Éléments communs

Queue<T> et Stack<T>

Collections spécialisées pour gérer des données selon des règles spécifiques.

Queue<T> - File (FIFO)

C#
Queue<string> fileAttente = new Queue<string>(); // Ajouter des éléments (à la fin) fileAttente.Enqueue("Alice"); fileAttente.Enqueue("Bob"); fileAttente.Enqueue("Charlie"); // Traiter les éléments (du début) while (fileAttente.Count > 0) { string suivant = fileAttente.Dequeue(); // Retire et retourne le premier Console.WriteLine($"Traitement de: {suivant}"); } // Consulter sans retirer if (fileAttente.Count > 0) { string prochain = fileAttente.Peek(); // Consulte sans retirer }

Stack<T> - Pile (LIFO)

C#
Stack<string> historique = new Stack<string>(); // Ajouter des éléments (au sommet) historique.Push("Page1"); historique.Push("Page2"); historique.Push("Page3"); // Traiter les éléments (du sommet) while (historique.Count > 0) { string page = historique.Pop(); // Retire et retourne le dernier Console.WriteLine($"Retour à: {page}"); } // Consulter sans retirer if (historique.Count > 0) { string actuelle = historique.Peek(); // Consulte le sommet }
Choisir la bonne collection :
  • List<T> : Collection générale, accès par index, ordre préservé
  • Dictionary<K,V> : Accès rapide par clé unique
  • HashSet<T> : Éléments uniques, pas d'ordre, tests de membership rapides
  • Queue<T> : Premier entré, premier sorti (FIFO)
  • Stack<T> : Dernier entré, premier sorti (LIFO)

LINQ avec les collections

Language Integrated Query (LINQ) permet de manipuler les collections facilement.

C#
using System.Linq; List<int> nombres = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // Filtrer List<int> pairs = nombres.Where(n => n % 2 == 0).ToList(); // {2, 4, 6, 8, 10} // Transformer List<int> carres = nombres.Select(n => n * n).ToList(); // {1, 4, 9, 16, ...} // Agréger int somme = nombres.Sum(); // 55 double moyenne = nombres.Average(); // 5.5 int maximum = nombres.Max(); // 10 int minimum = nombres.Min(); // 1 // Rechercher int premier = nombres.First(n => n > 5); // 6 bool existeGrand = nombres.Any(n => n > 100); // false bool tousPositifs = nombres.All(n => n > 0); // true // Trier List<int> tries = nombres.OrderByDescending(n => n).ToList(); // {10, 9, 8, ...}

Exercice pratique

Exercice :

Créez un système de gestion d'étudiants avec les fonctionnalités suivantes :

  1. Une classe Étudiant avec nom, âge, et liste de notes
  2. Un dictionnaire pour stocker les étudiants par numéro
  3. Des méthodes pour ajouter, rechercher, et calculer des statistiques
  4. Utilisation de LINQ pour les requêtes

Points clés à retenir