Introduction aux tableaux en Java

Qu'est-ce qu'un tableau ?

Un tableau est une structure de données qui permet de stocker plusieurs valeurs du même type de données dans un seul conteneur. Lors du stockage de données, il est essentiel de tenir compte de la conversion implicite.

Par exemple, si un tableau est défini pour contenir des entiers (int), il ne pourra pas stocker directement des valeurs booléennes (boolean) ou à virgule flottante (double). Cependant, il pourra stocker des valeurs de types plus petits comme byte ou short, qui seront implicitement converties en int.

Il est généralement recommandé que le type de données du conteneur (le tableau) corresponde au type des données qu'il contiendra.

  • Les entiers comme 1, 2, 3, 4, 56 peuvent être stockés dans un tableau de type int.
  • Les nombres décimaux comme 1.1, 1.2, 1.3, 1.4 peuvent être stockés dans un tableau de type double.
  • Les chaînes de caractères comme "aaa", "bbb", "ccc" peuvent être stockées dans un tableau de type String.

Déclaration d'un tableau

Il existe deux syntaxes pour déclarer un tableau :

Syntaxe 1 :

type [] nomDuTableau;

Exemple : int [] monTableau;

Syntaxe 2 :

type nomDuTableau [];

Exemple : int monTableau [];

Dans ces déclarations :

  • type spécifie le type des données que le tableau pourra contenir.
  • [] (les crochets) indiquent que l'on déclare un tableau.
  • nomDuTableau est le nom que vous donnez à votre tableau pour pouvoir y accéder plus tard.

La position des crochets (avant ou après le nom du tableau) n'affecte pas la fonctionnalité. Cependant, la première syntaxe (crochets après le type) est plus couramment utilisée et préférée.

Initialisation statique d'un tableau

L'initialisation statique permet de créer un tableau et de lui assigner des valeurs en une seule étape.

Format complet :

type [] nomDuTableau = new type [] {element1, element2, element3, ...};

Exemples :

int[] nombresEntiers = new int[] {11, 22, 33};
double[] nombresDecimaux = new double[] {1.1, 1.2, 1.3};

Explication des composants :

  • type : Définit le type des éléments du tableau.
  • [] : Indique que c'est un tableau.
  • nomDuTableau : Le nom du tableau, suivant la convention de nommage en camelCase.
  • new type [] : Alloue de l'espace mémoire pour le tableau. Le type ici doit correspondre au type déclaré précédemment.
  • {element1, element2, ...} : Les valeurs initiales du tableau, séparées par des virgules.

Attention : Le type spécifié avant new doit être le même que le type déclaré pour le tableau. Par exemple, int[] arr = new double[]{11, 22, 33}; est une erreur.

Format simplifié :

Si vous initialisez le tableau immédiatement après sa déclaration, vous pouvez omettre le new type [].

type [] nomDuTableau = {element1, element2, element3, ...};

Exemples :

int[] monTableauEntiers = {1, 2, 3, 4, 5};
double[] monTableauDecimaux = {1.1, 1.2, 1.3};

Point important : Une fois qu'un tableau est créé, sa taille est fixe et ne peut pas être modifiée.

Exercices d'initialisation statique :

Exercice 1 : Âges d'étudiants

Définir un tableau pour stocker l'âge de 5 étudiants.

// Type : int
int[] agesEtudiants = {18, 19, 20, 21, 22};

Exercice 2 : Noms d'étudiants

Définir un tableau pour stocker le nom de 3 étudiants.

// Type : String
String[] nomsEtudiants = {"Alice", "Bob", "Charlie"};

Exercice 3 : Tailles d'étudiants

Définir un tableau pour stocker la taille de 4 étudiants.

// Type : double
double[] taillesEtudiants = {1.85, 1.82, 1.78, 1.65};

Affichage de la valeur d'adresse

Lorsque vous essayez d'imprimer un tableau directement, vous n'obtenez pas ses éléments, mais sa valeur d'adresse mémoire.

int[] arrInt = {1, 2, 3, 4, 5};
System.out.println(arrInt); // Affichera quelque chose comme : [I@6d03e736

double[] arrDouble = {1.1, 2.2, 3.3};
System.out.println(arrDouble); // Affichera quelque chose comme : [D@568db2f2

La valeur d'adresse comme [I@6d03e736 se décompose ainsi :

  • [ : Indique que c'est un tableau.
  • I : Représente le type du tableau (I pour int). Pour les tableaux de chaînes, ce serait L.
  • @ : Un séparateur.
  • 6d03e736 : La véritable adresse mémoire du tableau, représentée en hexadécimal.

En pratique, cette valeur d'adresse est rarement utilisée directement par les développeurs ; c'est surtout pour comprendre comment Java gère la mémoire des tableaux.

Accès aux éléments d'un tableau

Pour accéder aux éléments d'un tableau, vous utilisez son nom suivi de l'indice de l'élément souhaité entre crochets.

Format :

nomDuTableau[indice];

Ce format permet de :

  • Obtenir la valeur d'un élément à un indice spécifique.
  • Modifier la valeur d'un élément à un indice spécifique. L'ancienne valeur sera écrasée.

Exemple de code :

public class AccesseurTableau {
    public static void main(String[] args) {
        int[] monTableau = {1, 2, 3, 4, 5};

        // Récupérer la valeur à l'indice 3
        int valeur = monTableau[3];
        System.out.println("Valeur à l'indice 3 : " + valeur); // Affichera 4
        System.out.println("Valeur à l'indice 3 (direct) : " + monTableau[3]); // Affichera 4

        // Modifier la valeur à l'indice 3
        monTableau[3] = 10;
        System.out.println("Nouvelle valeur à l'indice 3 : " + monTableau[3]); // Affichera 10
    }
}

Les indices

Les indices (également appelés "index" ou "subscript") sont les numéros qui identifient chaque position dans un tableau. Ils servent de référence pour accéder aux éléments.

Caractéristiques des indices :

  • Les indices commencent toujours à 0.
  • Les indices sont séquentiels (ils se suivent sans interruption).
  • Chaque indice est incrémenté de 1 par rapport au précédent.

Parcourir un tableau (Itération)

Parcourir un tableau signifie accéder à chacun de ses éléments, un par un. La longueur d'un tableau est accessible via la propriété .length.

Code général pour parcourir un tableau :

for (int i = 0; i < nomDuTableau.length; i++) {
    // 'i' représente l'indice courant du tableau
    // nomDuTableau[i] permet d'accéder à l'élément à l'indice 'i'
    System.out.println(nomDuTableau[i]); // Affiche chaque élément
}

Initialisation dynamique d'un tableau

L'initialisation dynamique permet de créer un tableau en spécifiant sa taille, sans définir immédiatement ses éléments. Les valeurs par défaut seront assignées selon le type des données.

Format :

type [] nomDuTableau = new type [tailleDuTableau];

Exemples :

// 1. Définir un tableau pour 3 âges, dont les valeurs ne sont pas encore connues
int[] agesInconnus = new int[3];

// 2. Définir un tableau pour 10 notes d'élèves, inconnues pour le moment
int[] notesEleves = new int[10];

Valeurs par défaut lors de l'initialisation dynamique :

  • Types numériques entiers (int, byte, short, long) : 0
  • Types numériques décimaux (float, double) : 0.0
  • Type booléen (boolean) : false
  • Type caractère (char) : '\u0000' (caractère nul)
  • Types référence (objets, tableaux, etc.) : null

Différences entre initialisation statique et dynamique

  • Initialisation statique : int[] arr = {1, 2, 3, 4, 5};
    Vous spécifiez directement les éléments. Le système calcule la taille du tableau en fonction du nombre d'éléments fournis.
  • Initialisation dynamique : int[] arr = new int[3];
    Vous spécifiez la taille du tableau. Le système remplit le tableau avec les valeurs par défaut appropriées au type.

Scénarios d'utilisation :

  • Utilisez l'initialisation dynamique lorsque vous connaissez le nombre d'éléments nécessaires mais pas leurs valeurs spécifiques (par exemple, stocker 5 entiers saisis au clavier : int[] nombres = new int[5];).
  • Utilisez l'initialisation statique lorsque vous connaissez toutes les valeurs que le tableau doit contenir dès le départ (par exemple, stocker les notes connues {66, 77, 88, 99, 100} : int[] notes = {66, 77, 88, 99, 100};. Essayer de le faire avec l'initialisation dynamique puis en assignant chaque valeur serait plus fastidieux).

Problèmes courants avec les tableaux

L'erreur la plus fréquente est l'exception de dépassement d'indice (ArrayIndexOutOfBoundsException). Elle se produit lorsque vous essayez d'accéder à un indice qui n'existe pas dans le tableau.

Pour éviter cela :

  • L'indice minimum valide pour un tableau est toujours 0.
  • L'indice maximum valide est longueurDuTableau - 1.
  • Vous pouvez obtenir la longueur maximale avec nomDuTableau.length - 1.

Exemple d'erreur d'indice :

public class ErreurIndice {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5}; // Longueur = 5, indices valides : 0, 1, 2, 3, 4

        System.out.println(arr[1]); // Valide, affiche 2

        // System.out.println(arr[10]); // Ceci lèverait une ArrayIndexOutOfBoundsException
    }
}

Représentation mémoire des tableaux

Comprendre comment les tableaux sont stockés en mémoire (pile vs tas) est important pour appréhender leur comportement, notamment lorsqu'on les assigne à d'autres variables.

Schémas mémoire :

(Note: Les schémas visuels ne peuvent pas être inclus dans ce format texte, mais ils illustreraient la différence entre la pile (pour les variables primitives) et le tas (pour les objets, y compris les tableaux). L'assignation d'un tableau à une autre variable copie la référence, pas les données.)

Exercices sur les tableaux

Exercice 1 : Somme des éléments

Définir un tableau avec les valeurs {1, 2, 3, 4, 5}. Calculer et afficher la some de tous ses éléments.

int[] arr = {1, 2, 3, 4, 5};
int somme = 0;
for (int i = 0; i < arr.length; i++) {
    somme += arr[i]; // Somme = Somme + arr[i]
}
System.out.println("La somme des éléments est : " + somme); // Affichera 15

Exercice 2 : Compter les multiples de 3

Définir un tableau avec les valeurs {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}. Compter et afficher combien de ces nombres sont divisibles par 3.

int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int compteur = 0;
for (int i = 0; i < arr.length; i++) {
    if (arr[i] % 3 == 0) {
        compteur++;
    }
}
System.out.println("Il y a " + compteur + " nombres divisibles par 3."); // Affichera 3

Exercice 3 : Modifier les éléments

Définir un tableau avec les valeurs {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}. Parcourir le tableau et :

  • Si un nombre est impair, multipliez-le par 2.
  • Si un nombre est pair, divisez-le par 2.
  • Affichez le tableau modifié.
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int i = 0; i < arr.length; i++) {
    if (arr[i] % 2 == 0) { // Nombre pair
        arr[i] = arr[i] / 2;
    } else { // Nombre impair
        arr[i] = arr[i] * 2;
    }
}
// Afficher le tableau modifié
for (int i = 0; i < arr.length; i++) {
    System.out.print(arr[i] + " ");
}
// Affichera : 2 1 6 2 10 3 14 4 18 5

Exercice 4 : Trouver la valeur maximale

Définir un tableau avec les valeurs {33, 5, 22, 44, 55}. Trouver et afficher la valeur maximale.

int[] arr = {33, 5, 22, 44, 55};
int max = arr[0]; // Initialiser avec le premier élément

// Commencer la boucle à l'indice 1 pour éviter une comparaison inutile avec soi-même
for (int i = 1; i < arr.length; i++) {
    if (arr[i] > max) {
        max = arr[i]; // Mettre à jour max si un élément plus grand est trouvé
    }
}
System.out.println("La valeur maximale est : " + max); // Affichera 55

Note sur l'initialisation de max : Il est crucial d'initialiser max avec un élément du tableau (par exemple arr[0]) plutôt qu'avec une valeur fixe comme 0. Si tous les éléments du tableau étaient négatifs, initialiser max à 0 donnerait un résultat incorrect. Commencer la boucle à l'indice 1 est une optimisation mineure.

Exercice 5 : Statistiques sur les nombres aléatoires

Générer 10 nombres aléatoires entre 1 et 100, les stocker dans un tableau, puis calculer :

  • La somme de tous les nombres.
  • La moyenne de ces nombres.
  • Le nombre d'éléments inférieurs à la moyenne.
import java.util.Random; // Nécessaire pour générer des nombres aléatoires

int[] arr = new int[10];
Random generateur = new Random();
int somme = 0;

// Générer les nombres aléatoires et les stocker, tout en calculant la somme
for (int i = 0; i < arr.length; i++) {
    int nombreAleatoire = generateur.nextInt(100) + 1; // Génère un nombre entre 0 (inclus) et 100 (exclus), puis ajoute 1
    arr[i] = nombreAleatoire;
    somme += nombreAleatoire;
}

// Calculer la moyenne
int moyenne = somme / arr.length;

// Compter les éléments inférieurs à la moyenne
int compteurInferieursMoyenne = 0;
for (int i = 0; i < arr.length; i++) {
    if (arr[i] < moyenne) {
        compteurInferieursMoyenne++;
    }
}

System.out.println("Somme des éléments : " + somme);
System.out.println("Moyenne : " + moyenne);
System.out.println("Nombre d'éléments inférieurs à la moyenne : " + compteurInferieursMoyenne);

// Optionnel : afficher le tableau généré pour vérification
System.out.print("Tableau généré : ");
for (int i = 0; i < arr.length; i++) {
    System.out.print(arr[i] + " ");
}
System.out.println();

Exercice 6 : Échanger des éléments

Définir un tableau avec les valeurs {1, 2, 3, 4, 5}. Échanger le premier et le dernier élément.

Avant : 1, 2, 3, 4, 5

Après : 5, 2, 3, 4, 1

int[] arr = {1, 2, 3, 4, 5};
int premiereValeur = arr[0];
arr[0] = arr[arr.length - 1]; // Échange le premier avec le dernier
arr[arr.length - 1] = premiereValeur; // Met la première valeur à la fin

// Afficher le tableau après échange
for (int i = 0; i < arr.length; i++) {
    System.out.print(arr[i] + " ");
}
System.out.println(); // Affichera : 5 2 3 4 1

Une approche plus générale pour échanger les éléments de manière symétrique (par exemple, échanger le 1er avec le dernier, le 2ème avec l'avant-dernier, etc.) utilise une boucle qui avance depuis le début et recule depuis la fin simlutanément.

int[] arr = {1, 2, 3, 4, 5};
for (int i = 0, j = arr.length - 1; i < j; i++, j--) {
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}
// Après cette boucle, le tableau sera : 5 4 3 2 1
// Si on voulait obtenir 5, 2, 3, 4, 1, il faudrait échanger uniquement le premier et le dernier.

Exercice 7 : Mélanger les données

Définir un tableau avec les valeurs {1, 2, 3, 4, 5}. Mélanger aléatoirement l'ordre des éléments du tableau.

import java.util.Random;

int[] arr = {1, 2, 3, 4, 5};
Random generateur = new Random();

for (int i = 0; i < arr.length; i++) {
    // Générer un indice aléatoire valide pour le tableau
    int indiceAleatoire = generateur.nextInt(arr.length);

    // Échanger l'élément courant (à l'indice i) avec l'élément à l'indice aléatoire
    int temp = arr[i];
    arr[i] = arr[indiceAleatoire];
    arr[indiceAleatoire] = temp;
}

// Afficher le tableau mélangé
for (int i = 0; i < arr.length; i++) {
    System.out.print(arr[i] + " ");
}
System.out.println();
// L'affichage sera différent à chaque exécution, par exemple : 3 1 5 2 4

Étiquettes: Java tableaux programmation initialisation statique initialisation dynamique

Publié le 20 juillet à 23h07