• 10 heures
  • Facile

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 23/04/2024

Gérez les piles de données avec la bonne collection

Imaginez que vous êtes le responsable de la communication d'un théâtre à la mode. Votre responsabilité principale consiste à gérer les premiers rangs, "Front Rows", c'est-à-dire à veiller à ce que les parents et amis invités ("Guests") par les artistes, ainsi que les autres VIP, obtiennent les meilleures places pour le spectacle.

Si tout ce que vous aviez à faire consistait à gérer deux invitations pour l'artiste principal, vous pourriez imaginer utiliser seulement deux variables de type String contenant le nom de l'invité. Le code Java ressemblerait à cela :

// Déclarez une variable pour chaque invité de la première rangée
String frontRowGuest1;
String frontRowGuest2;

Ensuite, lorsque l'artiste vous fournirait les informations, vous n'auriez qu'à attribuer un nom à chaque variable. Par exemple :

// Attribuez le nom des invités
frontRowGuest1="Mary Poppins";
frontRowGuest2="Jane Banks"

Si le premier rang compte 30 sièges, cela obligera à avoir 30 variables déclarées une par une. Ne serait-il pas plus facile d'utiliser une seule variable qui contiendrait toutes ces informations ?

Vous avez de la chance ! Java offre une structure de données capable de contenir un nombre fixe de valeurs d'un même type. Cette structure s'appelle un tableau (ou Array, en anglais). Voyons quand et comment en utiliser un.

Utilisez un tableau pour stocker un nombre fixe d'éléments

Un tableau est une liste ordonnée et numérotée d'éléments du même type (par exemple, un tableau de int ne contiendra que des int !). Chaque élément est associé à un numéro appelé index. L'indexation commence par 0 (pas 1 !), ce qui signifie que le premier élément est associé à un index 0, le deuxième à 1, etc.

Déclarer un tableau utilise la même syntaxe que pour n'importe quelle variable. Par exemple, pour stocker le nombre de tasses de café que vous buvez chaque jour de la semaine, vous pouvez déclarer un tableau d'entiers avec la syntaxe suivante :

// Déclarez la variable
int[] cupsOfCoffeePerDayOfTheWeek;

Vous fournissez :

  1. Le type des éléments que le tableau contiendra, suivi de   []  .

  2. Le nom de la variable qui doit expliciter clairement l'intention du tableau.

Instanciez ensuite le tableau avec sept emplacements (les sept jours de la semaine) :

// Créez le tableau et assignez-le à la variable
cupsOfCoffeePerDayOfTheWeek=new int[7];

Lorsque le tableau est créé, chaque élément est initialisé avec la valeur par défaut du type du tableau. Dans le cas d'un tableau de   int  , cela signifie 0.

Vous pouvez aussi déclarer et créer un tableau en une seule ligne. Voici ce que vous feriez pour déclarer une variable et l'initialiser directement avec un nouveau tableau de trois   int  :

Pour déclarer un tableau, on commence par le type (int) puis des crochets ouvrant et fermant, puis le nom du tableau suivi du signe égale (=). Ensuite on l'initialise avec le mot-clé et la valeur entre crochets. On n'oublie pas le point-virgule à la f
Déclaration d'un tableau

Pour en revenir à notre gestion hebdomadaire du café : maintenant que le tableau est créé, vous pouvez y effectuer deux opérations :

  1. Accéder à une valeur à un index donné.

  2. Définir une nouvelle valeur à un index donné.

Dans les deux cas, vous utilisez le nom de la variable suivi de   [  , la valeur de l'index, et   ]  .

Par exemple, si vous buvez trois cafés le cinquième jour de la semaine, vous pouvez écrire :

// Attribuez la valeur 3 au cinquième jour de la semaine
// C'est l'index 4, puisque le premier index est 0
cupsOfCoffeePerDayOfTheWeek[4]=3;

Pour afficher le nombre de cafés que vous buvez le premier jour de la semaine, vous pouvez écrire l'instruction suivante :

//Afficher le nombre de cafés le premier jour de la semaine
System.out.println(cupsOfCoffeePerDayOfTheWeek[0]);

Enfin, si vous souhaitez définir toutes les valeurs en même temps, vous pouvez également :

  • soit définir toutes les valeurs au moment de la création du tableau ;

  • soit utiliser une boucle qui définit chaque valeur, une par une.

Pour l'instant, créons un nouveau tableau et assignons-le à la variable  cupsOfCoffeePerDayOfTheWeek  :

//Créez un nouveau tableau avec toutes les valeurs et assignez-le à notre variable
cupsOfCoffeePerDayOfTheWeek=new int[]{6,2,3,7,3,4,1};

À vous de jouer !

Et le premier rang de notre salle de théâtre ? Eh bien, vous n'avez qu'à créer un tableau de chaînes avec le nombre de sièges que contient votre premier rang. Vous pouvez soit ajouter tous vos invités au moment de la création, soit les ajouter individuellement en utilisant la syntaxe   []  .

Essayez les tableaux avec l'exercice interactif suivant :

Pour accéder à l’exercice, suivez ce lien.

Si vous voulez aller plus loin et gérer tous les rangs de votre salle de spectacle, vous pouvez utiliser des tableaux multidimensionnels. Imaginons que votre théâtre contienne 30 rangs de 12 places. Voici comment créer un tableau et attribuer une valeur au sixième siège du dixième rang : 

// Créez un tableau multidimensionnel pour gérer tous les rangs d'un théâtre
String[][] myTheatreSeats=new String[30][12];
// Rang 10, siège 6. N'oubliez pas que l'index commence à 0!
myTheatreSeats[9][5]="James Logan";

Les tableaux sont efficaces et parfaits pour gérer un nombre fixe d'éléments. Dans la pratique, vous devez souvent gérer un nombre variable d'éléments. Java facilite le traitement de ces cas avec les collections.

Commençons par la collection la plus populaire d'entre toutes, la liste.

Utilisez des listes si le nombre d'éléments n'est pas fixe

Les tableaux sont bien pratiques, mais ils ont leurs limites :

  • ils ont une taille fixe ;

  • vous ne pouvez modifier que les valeurs existantes.

Imaginons que vous vouliez classer des animaux du plus mignon au moins mignon, et que vous commenciez par un petit tableau composé de quatre éléments : renard, hibou, koala et loutre. Disons que vous voulez ajouter un écureuil et le mettre entre le renard et le hibou.

Avec un tableau, vous ne pouvez pas insérer un élément supplémentaire, vous pouvez seulement remplacer des éléments. Vous ne pouvez pas non plus ajouter votre écureuil à la fin de la liste (en programmation, on appelle cela : append). Pour cela, il faudrait créer un tout nouveau tableau de cinq cases au lieu de quatre. Puis, vous devrez à nouveau ajouter tous vos éléments à la main. Ça a l'air plutôt long et ennuyeux, non ?

C'est là qu'une liste ordonnée entre en jeu ! Comme elles sont modifiables, vous pouvez modifier le contenu et le nombre d'éléments d'une collection. Après les restrictions des tableaux, cela peut sembler magique ! 

Un petit exemple pour voir ce dont on parle :

List<String> myList = new ArrayList<String>();

Entre autres choses, avec les listes, vous pouvez :

  • accéder à chaque élément via son index ;

  • ajouter (append) un nouvel élément à la fin ;

  • insérer un nouvel élément à un index spécifique ;

  • supprimer un nouvel élément à un index spécifique.

Répétons-le, il s'agit de changer la valeur, pas le type. Le type ne peut pas être changé, même avec la puissance impressionnante d'une   ArrayList  !

Très utile ! En Java, il existe plusieurs classes qui utilisent des listes, la plus utilisée étant l’ArrayList. Vous pouvez même créer la vôtre ! L'important est que la classe que vous sélectionnez utilise l'interface   List  . 

Une interface est un contrat qui définit toutes les opérations qu'une classe doit fournir. Dans le cas de l'interface   List  , vous pouvez vérifier toutes les opérations prises en charge et la manière d'utiliser les classes sur le site web officiel des tutoriels Java (ressource en anglais).

Dans la suite de ce chapitre, nous utiliserons la classe  ArrayList  . Voyons comment cela fonctionne en pratique !

Créez une liste et ajoutez des éléments

Pour créer une liste, vous devez :

  1. Déclarer une variable dont le type est l'interface   List  . Cela signifie que vous pouvez assigner n'importe quel objet à la variable qui met en place l'interface  List,  y compris la classe   ArrayList  .

  2. Initialiser la variable avec une expression commençant par le mot clé   new  qui crée une instance de la classe   ArrayList  .

Ceci peut être fait en une seule ligne avec la syntaxe suivante :

La déclaration a lieu avant l'opérateur d'affectation  =  . Tout d'abord, vous avez le type, qui est
Création d'une liste
  1. La déclaration a lieu avant l'opérateur d'affectation  =  . Tout d'abord, vous avez le type, qui est  List  . Ceci est directement suivi de   <Integer>  , qui est le paramètre de type pour la liste. Un paramètre de type limite le type d'objets qui peuvent être stockés dans la liste. Dans cet exemple, vous ne pourrez enregistrer que des nombres entiers.

  2. La création en tant que telle a lieu avec l'expression  new  ArrayList<Integer>()  . L'objet initialisé est assigné à la variable   myList  .

Vous avez peut-être remarqué que le mot   Integer  est écrit en toutes lettres et avec une majuscule. La raison à cela : une liste ne peut stocker que des objets, pas des types primitifs. De la même manière, vous devrez utiliser :

  • Double  au lieu de   double  si vous voulez stocker les décimales ;

  • Boolean  au lieu de   boolean  si vous voulez enregistrer des valeurs vraies/fausses ;

  • Float  au lieu de   float  si vous insistez vraiment pour les utiliser.

La version objet des types primitifs est très utile car équipée de méthodes. N’hésitez pas à consulter la documentation officielle (notamment pour les integer : https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html).

Mais qu'en est-il des choses que nous voulons mettre dans notre liste ?

Très bonne question ! Vous ne pouvez créer qu'une liste vide en Java. Pour y mettre des éléments, vous devez les ajouter un par un, comme ceci :

List<Integer> myList = new ArrayList<Integer>();
myList.add(7);
myList.add(5); //-> [7,5]
  1. La première affectation crée une liste vide appelée   myList  .

  2. Vous ajoutez ensuite un premier élément avec l'affectation   mylist.add(7)  . Java place automatiquement la valeur dans un objet  Integer  et l'ajoute à la liste à l'index 0.

  3. Enfin, l'affectation   myList.add(5)  crée une instance de la classe   Integer  avec une valeur de 5 et l'ajoute à la liste à l'index 1.

Maintenant, qu'est-ce qui se passe avec ce   .add()  ? En Java, ajouter, modifier ou supprimer des éléments nécessite l'utilisation d'une méthode, et vous l'avez deviné,   .add()  en est une ! À ce stade, tout ce que vous avez besoin de savoir sur les méthodes, c'est qu'elles vous permettent de faire des choses. 😎

Pour l'interface   List  , il y a trois méthodes implémentées par la classe   ArrayList  qui sont très pratiques :

  • add  – pour ajouter un nouvel élément à la fin d'un tableau. Ici, vous devez fournir un nouvel élément. Vous pouvez également insérer un nouvel élément à une position donnée en spécifiant l'index avant la valeur. Par exemple,   myList.add(1,12)  insère un entier avec la valeur 12 sur la position 1, et déplace la valeur existante sur la position 2, et ainsi de suite ;

  • set  – pour remplacer un nouvel élément sur un index spécifique. Ici, vous devez fournir un nouvel élément et l'index sur lequel vous voulez qu'une nouvelle valeur soit positionnée ;

  • remove  – pour supprimer un élément existant sur un index spécifique. Ici, vous devez fournir l'index de l'élément que vous souhaitez supprimer. Si vous n'avez plus besoin du premier élément, vous pouvez le retirer de la position 0. Cela déplacera le deuxième élément original de la position 1 à la position 0, le troisième de la position 2 à la position 1, et ainsi de suite.

Maintenant, à quoi est-ce que cela ressemble ? Voici la syntaxe Java pour ce qui précède :

List<Integer> myList = new ArrayList<Integer>(); // -> []
myList.add(7); // -> [7]
myList.add(5); //-> [7, 5]
myList.add(1,12) //-> [7, 12, 5]
myList.set(0,4); // -> [4, 12, 5]
myList.remove(1); // removed 12 -> [4, 5]

Décomposons cela un petit peu, d'accord ?

  • Vous pouvez voir la même opération que précédemment : ajouter 7 puis 5 à la liste.

  • Puis vous insérez 12 à l'index 1. La valeur existante de l'index 1 est déplacée vers l'index 2.

  • Ensuite, avec   .set()  , le premier nombre fait référence à l'index, et le second donne la valeur que vous voulez y mettre. En d'autres termes, vous demandez à votre   List  de modifier la valeur de l'index 0. Ceci transformera la valeur d'origine, 7, en nouvelle valeur, 4.

  • Pour finir, avec   .remove()  , vous demandez à votre liste de supprimer toute valeur trouvée à l'index 1. Cela veut dire que vous lui demandez de supprimer 12.

Ceci vous laisse avec votre liste finale contenant deux entiers : 4 et 5. Imaginez faire cela avec des tableaux de taille fixe !

Assurez le suivi du nombre d'éléments dans votre liste

Il y a une méthode très importante à utiliser avec une liste,   size()  , qui vous permet d'obtenir le nombre d'éléments dans une liste :

List<Integer> myList = new ArrayList<Integer>();
myList.add(1); // ->[1]
myList.add(2); //-> [1,2]
System.out.println(myList.size()); // -> 2

Ceci facilite grandement le suivi de l'emplacement des éléments de votre liste.

En bonus : vous pouvez aussi obtenir ces informations avec les tableaux ! Cependant, vous devrez utiliser la propriété   myArray.length  , au lieu de la méthode   myList.size()  que vous utilisez avec une liste.

La méthode   size()  est largement utilisée, notamment lorsque vous avez besoin de faire une boucle sur une liste (nous avons abordé les boucles dans le chapitre 6 de la partie 1).

Utilisez une collection non ordonnée – ensembles

Un ensemble (ou « set ») est une collection d'éléments uniques non ordonnés. Vous pouvez les utiliser si vous ne vous souciez pas de l’ordre de vos éléments – comme une liste d'ingrédients pour une recette par exemple.

Déclarez des ensembles

Comme pour les listes, Java a différentes classes pour gérer les ensembles. Nous allons nous concentrer sur l'ensemble le plus communément utilisé, le   HashSet  .

Regardons le code Java :

C'est comparable avec le fonctionnement d'une   ArrayList  : vous déclarez d'abord la variable avec l'interface
Déclaration d'un ensemble

Comme vous pouvez le voir, c'est assez comparable avec le fonctionnement d'une   ArrayList  . Vous déclarez d'abord la variable avec l'interface   Set  , et vous l'initialisez avec une instance de la classe concrète   HashSet  .

Manipulez les éléments d'un ensemble

Voici les opérations fréquentes que vous pouvez utiliser avec les ensembles :

  • ajouter un nouvel élément avec une nouvelle clé ;

  • supprimer un élément pour une clé spécifique ;

  • compter le nombre d'éléments de l'ensemble.

Et l'accès à un  élément  ?

Comme les ensembles sont des collections non ordonnées, il n'y a pas de moyen simple de pointer des éléments particuliers – du moins pas comme ceux que vous avez vus jusqu'ici. Il y a des façons de le faire, mais vous en apprendrez davantage à ce sujet au fur et à mesure que vous approfondirez vos connaissances en programmation.

Pour ajouter un nouvel élément, utilisez   add()  :

Set<String> ingredients = new HashSet<String>();
ingredients.add("eggs");
ingredients.add("sugar");
ingredients.add("butter");
ingredients.add("salt");

Comme les ensembles sont non ordonnés, il n'est pas nécessaire d'utiliser « append » ou d'insérer des éléments à un point spécifique. Il vous suffit d'utiliser   add()  !

Pour supprimer un élément, vous utilisez   remove()  :

Set<String> ingredients = new HashSet<>();
ingredients.add("salt"); //ajoutez du sel sur les ingrédients
ingredients.remove("salt"); //enlevez du sel des ingrédients

L'important, c'est de fournir l'élément exact à supprimer. Ici, vous vous débarrassez du « sel ».

Les ensembles, comme les listes, utilisent également la méthode   size()  pour obtenir le nombre d'éléments dans un ensemble :

System.out.println(ingredients.size());

Consultez les dictionnaires ou "maps"

Par exemple, si vous voulez lister les noms de vos amis et leur âge respectif, les dictionnaires sont la bonne collection à utiliser :

Éléments du dictionnaire présentant une liste de noms d'amis et leur âge respectif.
Éléments du dictionnaire

Toutes les clés d'un dictionnaire doivent être uniques, tout comme un numéro de plaque d'immatriculation de voiture est unique.

Déclarez des dictionnaires

Pour cette section, nous utiliserons la classe la plus courante,   HashMap  . Voici le code pour déclarer et initialiser une instance de cette classe :

La différence principale, en comparaison avec les listes et les ensembles, c'est qu'il faut paramétrer le dictionnaire avec deux éléments, en utilisant la syntaxe    .
Déclaration d'un dictionnaire

La différence principale, en comparaison avec les listes et les ensembles, réside dans le fait que vous paramétrez votre dictionnaire avec deux éléments, en utilisant la syntaxe  <String, Integer>  .

  1. String  est le type de la clé.

  2. Integer  est le type de la valeur.

Pour ajouter des éléments à votre dictionnaire, utilisez la méthode   myMap.put()  . Entre parenthèses, indiquez d'abord la clé, puis la valeur :

// Les âges de mes amis
myMap.put("Jenny", 34);
myMap.put("Livia", 28);
myMap.put("Paul", 31);
System.out.println(myMap.get("Jenny")); // -> 34

Dans la dernière ligne, nous avons demandé au programme d'afficher la valeur de la clé, Jenny. Dans ce code :

  • la méthode   System.out.println()  affiche le résultat d'une expression fournie entre parenthèses ;

  • l'expression réelle,   myMap.get("Jenny")  , renvoie la valeur identifiée par la touche "Jenny", qui est stockée dans la variable myMap.

Lorsque vous utilisez des chaînes comme clés, n'oubliez pas que ces clés sont sensibles à la casse. Ainsi, "Jenny" et "jenny" sont (par exemple) deux clés différentes associées à deux éléments différents dans un dictionnaire. Par exemple :

myMap.put("Jenny", 34);
myMap.put("Livia", 28);
myMap.put("Paul", 31);
myMap.put("jenny", 21);
System.out.println(myMap.get("Jenny")); // -> 34
System.out.println(myMap.get("jenny")); // -> 21

Pour éviter de telles situations, une astuce consiste à utiliser des constantes pour spécifier les clés une fois et les réutiliser ensuite dans tout le code :

// Définissez des clés en tant que constantes dans votre classe
private static final String KJENNY = "Jenny";
private static final String KLIVIA = "Livia";
private static final String KPAUL = "Paul";
// Utilisez des constantes en tant que keys
myMap.put(KJENNY, 34);
myMap.put(KLIVIA, 28);
myMap.put(KPAUL, 31);

// Accédez à un élément
System.out.println(myMap.get(KJENNY)); // -> 34

Vous voyez que vous devez utiliser ici les mots clés   private static final   pour indiquer que vous avez besoin que vos chaînes soient des constantes et non des variables. Ceci est très utile, car cela vous garantit que vous garderez vos clés pour toujours, et que vous ne perdrez aucune donnée en changeant accidentellement les chaînes de clés !

Si le type le plus couramment utilisé est   String  , les clés en Java peuvent être de différents types, par exemple   Integer  :

Map<Integer, String> myMap = new HashMap<Integer, String>();
morning.put(1, "Wake up");

Les dictionnaires ont en commun avec les types de variables et les tableaux simples, que leur type ne peut pas être modifié.

Toutes les clés doivent être du même type, et toutes les valeurs doivent être du même type.

myMap.put("Jenny", 34);
myMap.put("Livia", 28); // Ok
myMap.put("Paul", "Designer") // Error

Manipulez les éléments du dictionnaire

Voici les opérations fréquemment utilisées que vous pouvez effectuer avec les dictionnaires :

  • accéder à la valeur d'un élément par sa clé ;

  • ajouter un nouvel élément avec une nouvelle clé et une valeur ;

  • supprimer un élément pour une clé spécifique.

Imaginons un dictionnaire de noms de personnes et de leur profession, appelé « professions ».

  1. Vous pouvez ajouter une valeur avec une méthode   put()  et deux arguments : la clé et la valeur.

  2. Pour accéder à une valeur, utilisez simplement la méthode   get()  avec la clé en argument.

Allons jeter un coup d'œil à cela :

professions.put("Jenny", "Business owner");
System.out.println(professions.get("Jenny")); // -> Business owner

Vous pouvez également modifier un élément en réutilisant une clé existante avec la méthode

put()  :

professions.put("Jenny", "Business owner");
System.out.println(professions.get("Jenny")); // -> Business owner
professions.put("Jenny", "Developer");
System.out.println(professions.get("Jenny")); // -> Developer

Enfin, pour supprimer un élément, vous pouvez utiliser une méthode   remove()  avec la clé de l'élément que vous voulez supprimer :

professions.remove("Jenny");

Comptez les éléments

Les dictionnaires, comme les listes et les ensembles, ont aussi la propriété   size()  qui permet d'obtenir le nombre d'éléments du dictionnaire :

System.out.println(professions.size());

En résumé

Dans ce chapitre, vous avez appris les bases pour travailler avec des conteneurs qui stockent plusieurs éléments d'un type de données en particulier :

  • conteneurs de taille fixe : Arrays – les éléments d'un tableau sont indexés à partir de 0 et sont accessibles à l'aide de cet index. Le nombre d'éléments ne peut pas être modifié ;

  • listes ordonnées : Lists – les éléments d'une liste se comportent comme un tableau. Le nombre d'éléments peut évoluer en ajoutant et en supprimant des éléments ;

  • listes non ordonnées : Sets – les éléments d'un ensemble sont stockés sans ordre particulier. Vous pouvez y accéder en les énumérant ;

  • dictionnaires : Maps – les éléments d'un dictionnaire sont organisés par paires clé-valeur et sont accessibles à l'aide d'une clé ;

  • les actions les plus courantes effectuées avec les collections sont :

    • accéder à un élément,

    • ajouter un nouvel élément,

    • supprimer un élément,

    • modifier un élément,

    • compter tous les éléments,

    • parcourir tous les éléments.

La collection que vous choisissez dépend de la tâche à accomplir. Au fur et à mesure que vous progressez dans votre carrière, vous serez en mesure d'identifier le type le plus approprié à utiliser. Passons maintenant au passage de paramètres et des valeurs de retour. À tout de suite !

Exemple de certificat de réussite
Exemple de certificat de réussite