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 :
Le type des éléments que le tableau contiendra, suivi de
[]
.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 en revenir à notre gestion hebdomadaire du café : maintenant que le tableau est créé, vous pouvez y effectuer deux opérations :
Accéder à une valeur à un index donné.
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 :
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'interfaceList,
y compris la classeArrayList
.Initialiser la variable avec une expression commençant par le mot clé
new
qui crée une instance de la classeArrayList
.
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 estList
. 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.La création en tant que telle a lieu avec l'expression new
ArrayList<Integer>()
. L'objet initialisé est assigné à la variablemyList
.
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 dedouble
si vous voulez stocker les décimales ;Boolean
au lieu deboolean
si vous voulez enregistrer des valeurs vraies/fausses ;Float
au lieu defloat
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]
La première affectation crée une liste vide appelée
myList
.Vous ajoutez ensuite un premier élément avec l'affectation
mylist.add(7)
. Java place automatiquement la valeur dans un objetInteger
et l'ajoute à la liste à l'index 0.Enfin, l'affectation
myList.add(5)
crée une instance de la classeInteger
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 à votreList
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 :
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 :
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, réside dans le fait que vous paramétrez votre dictionnaire avec deux éléments, en utilisant la syntaxe <String, Integer>
.
String
est le type de la clé.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 ».
Vous pouvez ajouter une valeur avec une méthode
put()
et deux arguments : la clé et la valeur.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 !