Aller au contenu principal

Tableau

En Java, un tableau est une structure de données qui permet de stocker un ensemble d'éléments du même type, de manière contiguë en mémoire. Les tableaux sont des objets, mais ils sont considérés comme des types primitifs en Java.

Déclaration et instanciation d'un tableau

Pour déclarer un tableau, on utilise la syntaxe suivante :

type[] nomTableau;

type est le type des éléments du tableau et nomTableau est le nom de la variable qui référence le tableau.

Pour instancier un tableau, on utilise l'opérateur new :

nomTableau = new type[taille];

taille est le nombre d'éléments que le tableau peut contenir.

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

Les éléments d'un tableau sont accessibles par leur indice, qui commence à 0 pour le premier élément et va jusqu'à taille - 1 pour le dernier élément. On utilise la syntaxe suivante pour accéder à un élément :

nomTableau[indice]

Exemple

int[] tab = new int[5]; // Déclaration et instanciation d'un tableau d'entiers de taille 5

tab[0] = 10; // Affectation de la valeur 10 au premier élément du tableau
tab[1] = 20; // Affectation de la valeur 20 au deuxième élément du tableau

int x = tab[2]; // Récupération de la valeur du troisième élément du tableau

Parcours d'un tableau

On peut parcourir un tableau en utilisant une boucle for :

for (int i = 0; i < tab.length; i++) {
System.out.println(tab[i]);
}

Avantages et inconvénients des tableaux

Les tableaux sont une structure de données simple et efficace pour stocker un ensemble d'éléments du même type. Ils sont particulièrement utiles lorsque la taille du tableau est connue à l'avance et ne change pas au cours du programme.

Cependant, les tableaux ont une taille fixe, ce qui signifie qu'on ne peut pas ajouter ou supprimer d'éléments après la création du tableau. Si on a besoin d'une structure de données qui peut grandir ou rétrécir dynamiquement, il est préférable d'utiliser une autre structure de données, comme une ArrayList.

En résumé, les tableaux en Java sont :

  • Statiques : leur taille est fixée à la création et ne peut pas être modifiée.
  • Homogènes : tous les éléments doivent être du même type.
  • Indexés : les éléments sont accessibles par leur indice, qui commence à 0.

Tableaux Multidimensionnels

Les tableaux multidimensionnels permettent de stocker des données organisées en plusieurs dimensions. Le cas le plus courant est le tableau à deux dimensions (tableau 2D), qui peut être visualisé comme une matrice avec des lignes et des colonnes.

Tableaux à deux dimensions (2D)

Déclaration et instanciation

Pour déclarer un tableau à deux dimensions, on utilise deux paires de crochets :

type[][] nomTableau;

Pour l'instancier :

nomTableau = new type[nombreLignes][nombreColonnes];

Exemple : Création d'une matrice 3x4

int[][] matrice = new int[3][4]; // 3 lignes, 4 colonnes

// Affectation de valeurs
matrice[0][0] = 1;
matrice[0][1] = 2;
matrice[1][0] = 5;
matrice[2][3] = 12;

Initialisation lors de la déclaration

On peut aussi initialiser un tableau 2D directement :

int[][] matrice = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};

Parcours d'un tableau 2D

Pour parcourir un tableau à deux dimensions, on utilise deux boucles imbriquées :

int[][] matrice = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};

// Parcours avec indices
for (int i = 0; i < matrice.length; i++) { // Pour chaque ligne
for (int j = 0; j < matrice[i].length; j++) { // Pour chaque colonne
System.out.print(matrice[i][j] + " ");
}
System.out.println(); // Nouvelle ligne après chaque ligne de la matrice
}

Sortie :

1 2 3
4 5 6
7 8 9

Parcours avec for-each

for (int[] ligne : matrice) { // Pour chaque ligne
for (int valeur : ligne) { // Pour chaque valeur dans la ligne
System.out.print(valeur + " ");
}
System.out.println();
}

Exemple pratique : Tableau de notes

// Tableau représentant les notes de 4 étudiants pour 3 examens
double[][] notes = {
{85.5, 92.0, 88.5}, // Étudiant 1
{78.0, 85.5, 91.0}, // Étudiant 2
{92.5, 89.0, 94.5}, // Étudiant 3
{88.0, 86.5, 90.0} // Étudiant 4
};

// Calcul de la moyenne de chaque étudiant
for (int i = 0; i < notes.length; i++) {
double somme = 0;
for (int j = 0; j < notes[i].length; j++) {
somme += notes[i][j];
}
double moyenne = somme / notes[i].length;
System.out.println("Moyenne de l'étudiant " + (i + 1) + " : " + moyenne);
}

Tableaux irréguliers (Jagged Arrays)

En Java, contrairement à d'autres langages, les tableaux 2D ne sont pas obligés d'avoir le même nombre de colonnes pour chaque ligne. C'est ce qu'on appelle des tableaux irréguliers ou jagged arrays.

Pourquoi des tableaux irréguliers ?

Les tableaux irréguliers sont utiles lorsque :

  • Chaque ligne représente des données de tailles variables
  • On veut économiser de la mémoire en n'allouant que l'espace nécessaire
  • Les données ont naturellement une structure triangulaire ou pyramidale

Déclaration et création

int[][] tableauIrregulier = new int[3][]; // 3 lignes, colonnes non définies

tableauIrregulier[0] = new int[2]; // Première ligne : 2 éléments
tableauIrregulier[1] = new int[4]; // Deuxième ligne : 4 éléments
tableauIrregulier[2] = new int[3]; // Troisième ligne : 3 éléments

// Ou avec initialisation directe
int[][] triangle = {
{1},
{2, 3},
{4, 5, 6},
{7, 8, 9, 10}
};

Parcours d'un tableau irrégulier

Important : On doit utiliser tableau[i].length pour chaque ligne car elles peuvent avoir des longueurs différentes !

int[][] triangle = {
{1},
{2, 3},
{4, 5, 6},
{7, 8, 9, 10}
};

// Parcours sécuritaire
for (int i = 0; i < triangle.length; i++) {
for (int j = 0; j < triangle[i].length; j++) { // IMPORTANT : triangle[i].length
System.out.print(triangle[i][j] + " ");
}
System.out.println();
}

Sortie :

1
2 3
4 5 6
7 8 9 10

Exemple pratique : Historique de transactions

// Chaque client a un nombre différent de transactions
int[][] transactionsParClient = new int[4][];

transactionsParClient[0] = new int[]{100, 250, 75}; // Client 1 : 3 transactions
transactionsParClient[1] = new int[]{500}; // Client 2 : 1 transaction
transactionsParClient[2] = new int[]{25, 80, 120, 200, 150}; // Client 3 : 5 transactions
transactionsParClient[3] = new int[]{300, 400}; // Client 4 : 2 transactions

// Calcul du total par client
for (int i = 0; i < transactionsParClient.length; i++) {
int total = 0;
for (int j = 0; j < transactionsParClient[i].length; j++) {
total += transactionsParClient[i][j];
}
System.out.println("Client " + (i + 1) + " : " +
transactionsParClient[i].length + " transactions, total : " + total + "$");
}

Sortie :

Client 1 : 3 transactions, total : 425$
Client 2 : 1 transactions, total : 500$
Client 3 : 5 transactions, total : 575$
Client 4 : 2 transactions, total : 700$

Avantages des tableaux irréguliers

  1. Économie de mémoire : On n'alloue que l'espace nécessaire
  2. Flexibilité : Chaque ligne peut avoir sa propre taille
  3. Représentation naturelle : Idéal pour des données comme un triangle de Pascal

Tableaux à trois dimensions et plus

On peut créer des tableaux avec plus de deux dimensions :

// Tableau 3D : peut représenter un cube
int[][][] cube = new int[3][4][5]; // 3 couches, 4 lignes, 5 colonnes

// Accès à un élément
cube[0][2][3] = 42;

// Parcours d'un tableau 3D
for (int i = 0; i < cube.length; i++) {
for (int j = 0; j < cube[i].length; j++) {
for (int k = 0; k < cube[i][j].length; k++) {
System.out.println("cube[" + i + "][" + j + "][" + k + "] = " + cube[i][j][k]);
}
}
}

Exemple : Grille de Tic-Tac-Toe

char[][] grilleTicTacToe = new char[3][3];

// Initialisation de la grille avec des espaces vides
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
grilleTicTacToe[i][j] = '-';
}
}

// Placer des coups
grilleTicTacToe[0][0] = 'X'; // X joue au coin supérieur gauche
grilleTicTacToe[1][1] = 'O'; // O joue au centre
grilleTicTacToe[0][2] = 'X'; // X joue au coin supérieur droit

// Affichage de la grille
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
System.out.print(grilleTicTacToe[i][j] + " ");
}
System.out.println();
}

Sortie :

X - X
- O -
- - -

Points importants sur les tableaux multidimensionnels

  1. Taille : matrice.length donne le nombre de lignes, matrice[0].length donne le nombre de colonnes de la première ligne
  2. Mémoire : Un tableau 2D est en réalité un tableau de tableaux (tableau de références)
  3. Flexibilité : Les lignes peuvent avoir des tailles différentes (tableaux irréguliers)
  4. Performance : L'accès aux éléments est en O(1), mais le parcours complet nécessite plusieurs boucles imbriquées

Tableaux d'Objets et de Classes

Jusqu'à présent, nous avons vu des tableaux de types primitifs (int, double, char, etc.). Mais en Java, les tableaux peuvent également contenir des objets et des instances de classes personnalisées.

Tableaux de String (objets)

String est une classe en Java, donc un tableau de String est un tableau d'objets :

// Déclaration et initialisation
String[] noms = {"Alice", "Bob", "Charlie", "Diana"};

// Ou séparément
String[] prenoms = new String[3];
prenoms[0] = "Jean";
prenoms[1] = "Marie";
prenoms[2] = "Pierre";

// Parcours
for (String nom : noms) {
System.out.println("Bonjour " + nom);
}

Tableaux d'objets personnalisés

Imaginons qu'on veuille gérer plusieurs étudiants dans un programme. Au lieu de créer plusieurs variables séparées, on peut utiliser un tableau !

Exemple simple (aperçu pour le prochain chapitre)

// Supposons qu'on a une classe Etudiant (détails au prochain chapitre)
class Etudiant {
String nom;
double moyenne;

public Etudiant(String nom, double moyenne) {
this.nom = nom;
this.moyenne = moyenne;
}
}

// Création d'un tableau d'étudiants
Etudiant[] classe = new Etudiant[3];

// Initialisation de chaque élément
classe[0] = new Etudiant("Alice", 85.5);
classe[1] = new Etudiant("Bob", 92.0);
classe[2] = new Etudiant("Charlie", 78.5);

// Parcours et affichage
for (int i = 0; i < classe.length; i++) {
System.out.println(classe[i].nom + " : " + classe[i].moyenne);
}

Sortie :

Alice : 85.5
Bob : 92.0
Charlie : 78.5

Initialisation directe

Etudiant[] classe = {
new Etudiant("Alice", 85.5),
new Etudiant("Bob", 92.0),
new Etudiant("Charlie", 78.5)
};

Différence importante : Références vs Valeurs

Point crucial : Un tableau d'objets contient des références aux objets, pas les objets eux-mêmes !

Etudiant[] groupe1 = new Etudiant[2];
// À ce stade, groupe1[0] et groupe1[1] sont null !
// Il faut créer les objets :

groupe1[0] = new Etudiant("Alice", 85.5); // Maintenant groupe1[0] référence un objet
groupe1[1] = new Etudiant("Bob", 92.0); // Maintenant groupe1[1] référence un objet

Illustration :

Tableau groupe1 :
[0] → null (initialement)
[1] → null (initialement)

Après création :
[0] → Etudiant{nom: "Alice", moyenne: 85.5}
[1] → Etudiant{nom: "Bob", moyenne: 92.0}

Exemple pratique : Gestion d'un inventaire

class Produit {
String nom;
double prix;
int quantite;

public Produit(String nom, double prix, int quantite) {
this.nom = nom;
this.prix = prix;
this.quantite = quantite;
}

public double valeurTotale() {
return prix * quantite;
}
}

// Création d'un inventaire
Produit[] inventaire = {
new Produit("Ordinateur", 999.99, 5),
new Produit("Souris", 29.99, 25),
new Produit("Clavier", 79.99, 15)
};

// Calcul de la valeur totale de l'inventaire
double valeurTotale = 0;
for (Produit produit : inventaire) {
valeurTotale += produit.valeurTotale();
System.out.println(produit.nom + " : " + produit.quantite +
" unités, valeur : " + produit.valeurTotale() + "$");
}
System.out.println("Valeur totale de l'inventaire : " + valeurTotale + "$");

Sortie :

Ordinateur : 5 unités, valeur : 4999.95$
Souris : 25 unités, valeur : 749.75$
Clavier : 15 unités, valeur : 1199.85$
Valeur totale de l'inventaire : 6949.55$

Tableaux 2D d'objets

On peut aussi créer des tableaux multidimensionnels d'objets :

// Une grille de produits dans un magasin
Produit[][] rayons = new Produit[3][4]; // 3 rayons, 4 produits par rayon

// Remplissage
rayons[0][0] = new Produit("Pomme", 1.99, 50);
rayons[0][1] = new Produit("Banane", 0.99, 100);
// ... etc.

// Parcours
for (int i = 0; i < rayons.length; i++) {
System.out.println("Rayon " + (i + 1) + " :");
for (int j = 0; j < rayons[i].length; j++) {
if (rayons[i][j] != null) { // ATTENTION - Vérifier null !
System.out.println(" - " + rayons[i][j].nom);
}
}
}

Pourquoi des tableaux d'objets ?

Les tableaux d'objets permettent de :

  1. Organiser des données complexes : Un étudiant a plusieurs attributs (nom, notes, etc.)
  2. Regrouper logiquement : Tous les étudiants d'une classe dans un seul tableau
  3. Manipuler facilement : Trier, filtrer, calculer des statistiques sur l'ensemble
  4. Préparer pour les collections : Concept de base pour ArrayList, HashMap, etc. (vus plus tard)

Les tableaux d'objets deviennent alors extrêmement puissants pour organiser et manipuler des données complexes dans nos programmes.