Aller au contenu

Semaine 1 : JOUR 4 – Tableaux et introduction aux collections

Cours théorique (Matin - 3h)

4.1 Les tableaux (arrays)

Déclaration et initialisation :

// Déclaration d'un tableau
int[] nombres;  // Tableau d'entiers (style Java)
// ou : int nombres[];  (style C, moins utilisé)

// Initialisation avec taille
nombres = new int[5];  // Tableau de 5 entiers (valeurs par défaut : 0)

// Déclaration et initialisation en une ligne
int[] notes = new int[10];

// Initialisation avec valeurs
int[] jours = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

// COMPARAISON COBOL :
// 01 NOMBRES.
//    05 NOMBRE PIC 9(5) OCCURS 5 TIMES.

Accès aux éléments :

int[] notes = {12, 15, 18, 14, 16};

// Accès par index (commence à 0, comme en COBOL moderne)
int premiereNote = notes[0];  // 12
int deuxiemeNote = notes[1];  // 15

// Modification
notes[0] = 20;

// Longueur du tableau
int taille = notes.length;  // 5 (propriété, pas méthode !)

// ATTENTION : ArrayIndexOutOfBoundsException si index invalide
// notes[10] = 5;  // ERREUR à l'exécution !

Parcours de tableaux :

int[] notes = {12, 15, 18, 14, 16};

// Boucle for classique
for (int i = 0; i < notes.length; i++) {
    System.out.println("Note " + i + ": " + notes[i]);
}

// Boucle for-each (NOUVEAU, très pratique)
for (int note : notes) {
    System.out.println("Note: " + note);
}

// COMPARAISON COBOL :
// PERFORM VARYING I FROM 1 BY 1 UNTIL I > 5
//     DISPLAY "Note: " NOMBRE(I)
// END-PERFORM

Tableaux multidimensionnels :

// Tableau 2D (matrice)
int[][] matrice = new int[3][4];  // 3 lignes, 4 colonnes

// Initialisation avec valeurs
int[][] notes = {
    {12, 15, 18},  // Étudiant 1
    {14, 16, 13},  // Étudiant 2
    {10, 11, 15}   // Étudiant 3
};

// Accès
int noteEtudiant2Matiere3 = notes[1][2];  // 13

// Parcours
for (int i = 0; i < notes.length; i++) {
    for (int j = 0; j < notes[i].length; j++) {
        System.out.println("Étudiant " + i + ", matière " + j + ": " + notes[i][j]);
    }
}

// COMPARAISON COBOL :
// 01 NOTES.
//    05 ETUDIANT OCCURS 3 TIMES.
//       10 NOTE PIC 99 OCCURS 3 TIMES.

4.2 Limitations des tableaux et intro aux collections

Problèmes des tableaux :

  1. Taille fixe (définie à la création)
  2. Pas de méthodes pour ajouter/supprimer des éléments
  3. Pas de recherche intégrée
// Tableau : taille fixe
int[] tableau = new int[5];
// Impossible d'ajouter un 6ème élément !

// En COBOL, même limitation avec OCCURS

Introduction à ArrayList (collection dynamique) :

import java.util.ArrayList;

// ArrayList : taille dynamique
ArrayList<Integer> liste = new ArrayList<>();

// Ajout d'éléments
liste.add(10);
liste.add(20);
liste.add(30);

// Taille
int taille = liste.size();  // 3

// Accès
int valeur = liste.get(0);  // 10

// Modification
liste.set(1, 25);  // Remplace 20 par 25

// Suppression
liste.remove(2);  // Supprime l'élément à l'index 2

// AVANTAGE : taille dynamique, méthodes pratiques
// DÉSAVANTAGE : un peu plus lent que les tableaux

Comparaison tableau vs ArrayList :

// Tableau : performance, taille fixe
int[] tableau = new int[1000];
tableau[0] = 42;

// ArrayList : flexibilité, taille dynamique
ArrayList<Integer> liste = new ArrayList<>();
liste.add(42);
liste.add(43);  // Pas de limite !

// RÈGLE :
// - Utilisez un tableau si la taille est connue et fixe
// - Utilisez ArrayList si la taille peut changer

4.3 Manipulation avancée de tableaux

Copie de tableaux :

int[] source = {1, 2, 3, 4, 5};

// Copie superficielle (référence)
int[] refCopie = source;  // Même tableau !
refCopie[0] = 99;  // Modifie aussi source

// Copie profonde (nouveau tableau)
int[] vraieCopie = new int[source.length];
for (int i = 0; i < source.length; i++) {
    vraieCopie[i] = source[i];
}

// Ou avec System.arraycopy
int[] copie2 = new int[source.length];
System.arraycopy(source, 0, copie2, 0, source.length);

// Ou avec Arrays.copyOf (plus simple)
import java.util.Arrays;
int[] copie3 = Arrays.copyOf(source, source.length);

Tri et recherche :

import java.util.Arrays;

int[] nombres = {5, 2, 8, 1, 9, 3};

// Tri
Arrays.sort(nombres);  // Tri en place
System.out.println(Arrays.toString(nombres));  // [1, 2, 3, 5, 8, 9]

// Recherche binaire (tableau DOIT être trié)
int index = Arrays.binarySearch(nombres, 5);  // Retourne l'index de 5

// Comparaison
int[] autreTableau = {1, 2, 3, 5, 8, 9};
boolean identique = Arrays.equals(nombres, autreTableau);  // true

Travaux Pratiques (Après-midi - 4h)

TP4 : Tableaux et collections

Exercice 1 : Conversion COBOL → Java - Table OCCURS (1h)

Convertir ce programme COBOL :

01 VENTES-MENSUELLES.
   05 VENTE-MOIS PIC 9(7)V99 OCCURS 12 TIMES.
01 TOTAL-ANNUEL PIC 9(9)V99.
01 MOYENNE PIC 9(7)V99.
01 I PIC 99.

PROCEDURE DIVISION.
    * Initialisation des ventes
    MOVE 12500.50 TO VENTE-MOIS(1).
    MOVE 15200.75 TO VENTE-MOIS(2).
    MOVE 13800.00 TO VENTE-MOIS(3).
    * ... (autres mois)
    
    * Calcul total
    MOVE ZERO TO TOTAL-ANNUEL.
    PERFORM VARYING I FROM 1 BY 1 UNTIL I > 12
        ADD VENTE-MOIS(I) TO TOTAL-ANNUEL
    END-PERFORM.
    
    * Calcul moyenne
    DIVIDE TOTAL-ANNUEL BY 12 GIVING MOYENNE.
    
    DISPLAY "Total annuel: " TOTAL-ANNUEL.
    DISPLAY "Moyenne mensuelle: " MOYENNE.

Corrigé :

public class VentesMensuelles {
    public static void main(String[] args) {
        // Tableau des ventes mensuelles (12 mois)
        double[] venteMois = new double[12];
        
        // Initialisation des ventes (quelques mois)
        venteMois[0] = 12500.50;   // Janvier (index 0)
        venteMois[1] = 15200.75;   // Février
        venteMois[2] = 13800.00;   // Mars
        venteMois[3] = 14500.25;   // Avril
        venteMois[4] = 16200.00;   // Mai
        venteMois[5] = 15800.50;   // Juin
        venteMois[6] = 17500.00;   // Juillet
        venteMois[7] = 16900.75;   // Août
        venteMois[8] = 14200.00;   // Septembre
        venteMois[9] = 15600.50;   // Octobre
        venteMois[10] = 16800.25;  // Novembre
        venteMois[11] = 18900.00;  // Décembre
        
        // Calcul du total annuel
        double totalAnnuel = 0.0;
        for (int i = 0; i < venteMois.length; i++) {
            totalAnnuel += venteMois[i];
        }
        
        // Calcul de la moyenne
        double moyenne = totalAnnuel / venteMois.length;
        
        // Affichage des résultats
        System.out.println("=== VENTES MENSUELLES ===");
        System.out.println();
        
        String[] nomsMois = {"Janvier", "Février", "Mars", "Avril", "Mai", "Juin",
                            "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"};
        
        for (int i = 0; i < venteMois.length; i++) {
            System.out.printf("%s: %.2f EUR%n", nomsMois[i], venteMois[i]);
        }
        
        System.out.println();
        System.out.printf("Total annuel: %.2f EUR%n", totalAnnuel);
        System.out.printf("Moyenne mensuelle: %.2f EUR%n", moyenne);
        
        // Recherche meilleur et pire mois
        double max = venteMois[0];
        double min = venteMois[0];
        int moisMax = 0, moisMin = 0;
        
        for (int i = 1; i < venteMois.length; i++) {
            if (venteMois[i] > max) {
                max = venteMois[i];
                moisMax = i;
            }
            if (venteMois[i] < min) {
                min = venteMois[i];
                moisMin = i;
            }
        }
        
        System.out.println();
        System.out.println("Meilleur mois: " + nomsMois[moisMax] + " (" + max + " EUR)");
        System.out.println("Pire mois: " + nomsMois[moisMin] + " (" + min + " EUR)");
    }
}

Exercice 2 : Gestion de stock avec ArrayList (1h)

Créer un système simple de gestion de stock avec quantités dynamiques.

Corrigé :

import java.util.ArrayList;

public class GestionStock {
    public static void main(String[] args) {
        // Listes pour les codes produits et quantités
        ArrayList<String> codesProduits = new ArrayList<>();
        ArrayList<Integer> quantites = new ArrayList<>();
        
        // Ajout de produits au stock
        ajouterProduit(codesProduits, quantites, "PRD001", 150);
        ajouterProduit(codesProduits, quantites, "PRD002", 75);
        ajouterProduit(codesProduits, quantites, "PRD003", 200);
        ajouterProduit(codesProduits, quantites, "PRD004", 50);
        
        // Affichage du stock
        afficherStock(codesProduits, quantites);
        
        // Modification de quantité
        modifierQuantite(codesProduits, quantites, "PRD002", 100);
        
        // Suppression d'un produit
        supprimerProduit(codesProduits, quantites, "PRD004");
        
        // Affichage final
        System.out.println("\n=== STOCK APRÈS MODIFICATIONS ===");
        afficherStock(codesProduits, quantites);
        
        // Statistiques
        int total = calculerQuantiteTotale(quantites);
        System.out.println("\nQuantité totale en stock: " + total);
        
        // Alertes stock faible
        System.out.println("\nAlertes stock faible (< 100):");
        for (int i = 0; i < codesProduits.size(); i++) {
            if (quantites.get(i) < 100) {
                System.out.println("  " + codesProduits.get(i) + ": " + quantites.get(i));
            }
        }
    }
    
    static void ajouterProduit(ArrayList<String> codes, ArrayList<Integer> qtes, 
                               String code, int quantite) {
        codes.add(code);
        qtes.add(quantite);
        System.out.println("Produit ajouté: " + code + " (qté: " + quantite + ")");
    }
    
    static void afficherStock(ArrayList<String> codes, ArrayList<Integer> qtes) {
        System.out.println("\n=== STOCK ACTUEL ===");
        for (int i = 0; i < codes.size(); i++) {
            System.out.println(codes.get(i) + ": " + qtes.get(i) + " unités");
        }
    }
    
    static void modifierQuantite(ArrayList<String> codes, ArrayList<Integer> qtes,
                                String code, int nouvelleQte) {
        int index = codes.indexOf(code);
        if (index != -1) {
            qtes.set(index, nouvelleQte);
            System.out.println("Quantité modifiée pour " + code + ": " + nouvelleQte);
        } else {
            System.out.println("Produit non trouvé: " + code);
        }
    }
    
    static void supprimerProduit(ArrayList<String> codes, ArrayList<Integer> qtes,
                                String code) {
        int index = codes.indexOf(code);
        if (index != -1) {
            codes.remove(index);
            qtes.remove(index);
            System.out.println("Produit supprimé: " + code);
        } else {
            System.out.println("Produit non trouvé: " + code);
        }
    }
    
    static int calculerQuantiteTotale(ArrayList<Integer> qtes) {
        int total = 0;
        for (int qte : qtes) {
            total += qte;
        }
        return total;
    }
}

Exercice 3 : Tableau 2D - Grille de notes (1h)

Gérer les notes de plusieurs étudiants dans plusieurs matières.

Corrigé :

public class GrilleNotes {
    public static void main(String[] args) {
        // Grille : 4 étudiants x 3 matières
        double[][] notes = {
            {12.5, 15.0, 14.5},  // Étudiant 0
            {16.0, 13.5, 17.0},  // Étudiant 1
            {10.0, 11.5, 12.0},  // Étudiant 2
            {18.0, 16.5, 19.0}   // Étudiant 3
        };
        
        String[] nomsEtudiants = {"Alice", "Bob", "Charlie", "Diana"};
        String[] nomsMatieres = {"Mathématiques", "Physique", "Informatique"};
        
        // Affichage de la grille
        System.out.println("=== GRILLE DE NOTES ===");
        System.out.println();
        
        System.out.printf("%-12s", "Étudiant");
        for (String matiere : nomsMatieres) {
            System.out.printf("%-15s", matiere);
        }
        System.out.printf("%-10s%n", "Moyenne");
        System.out.println("-".repeat(70));
        
        for (int i = 0; i < notes.length; i++) {
            System.out.printf("%-12s", nomsEtudiants[i]);
            double somme = 0;
            for (int j = 0; j < notes[i].length; j++) {
                System.out.printf("%-15.2f", notes[i][j]);
                somme += notes[i][j];
            }
            double moyenne = somme / notes[i].length;
            System.out.printf("%-10.2f%n", moyenne);
        }
        
        // Moyennes par matière
        System.out.println();
        System.out.println("=== MOYENNES PAR MATIÈRE ===");
        for (int j = 0; j < nomsMatieres.length; j++) {
            double somme = 0;
            for (int i = 0; i < notes.length; i++) {
                somme += notes[i][j];
            }
            double moyenne = somme / notes.length;
            System.out.printf("%s: %.2f%n", nomsMatieres[j], moyenne);
        }
        
        // Meilleure note globale
        double meilleureNote = notes[0][0];
        String meilleurEtudiant = "";
        String meilleureMatiere = "";
        
        for (int i = 0; i < notes.length; i++) {
            for (int j = 0; j < notes[i].length; j++) {
                if (notes[i][j] > meilleureNote) {
                    meilleureNote = notes[i][j];
                    meilleurEtudiant = nomsEtudiants[i];
                    meilleureMatiere = nomsMatieres[j];
                }
            }
        }
        
        System.out.println();
        System.out.println("Meilleure note: " + meilleureNote + " (" + 
                          meilleurEtudiant + " en " + meilleureMatiere + ")");
    }
}

Exercice 4 : Mini-projet - Analyse de données de production (1h)

Analyser des données de production quotidienne.

Corrigé :

import java.util.Arrays;

public class AnalyseProduction {
    public static void main(String[] args) {
        // Données de production sur 30 jours
        int[] productionJournaliere = {
            1250, 1180, 1320, 1290, 1150,  // Semaine 1
            1400, 1350, 1420, 1380, 1310,  // Semaine 2
            1200, 1150, 1100, 1080, 1220,  // Semaine 3
            1340, 1370, 1390, 1410, 1360,  // Semaine 4
            1180, 1200, 1240, 1280, 1320,  // Semaine 5
            1350, 1380, 1400, 1420, 1450   // Semaine 6
        };
        
        System.out.println("=== ANALYSE PRODUCTION (30 JOURS) ===");
        System.out.println();
        
        // 1. Production totale
        int total = 0;
        for (int prod : productionJournaliere) {
            total += prod;
        }
        System.out.println("Production totale: " + total + " unités");
        
        // 2. Moyenne quotidienne
        double moyenne = (double) total / productionJournaliere.length;
        System.out.printf("Moyenne quotidienne: %.2f unités%n", moyenne);
        
        // 3. Production min et max
        int min = productionJournaliere[0];
        int max = productionJournaliere[0];
        int jourMin = 1, jourMax = 1;
        
        for (int i = 0; i < productionJournaliere.length; i++) {
            if (productionJournaliere[i] < min) {
                min = productionJournaliere[i];
                jourMin = i + 1;
            }
            if (productionJournaliere[i] > max) {
                max = productionJournaliere[i];
                jourMax = i + 1;
            }
        }
        
        System.out.println();
        System.out.println("Production minimale: " + min + " (jour " + jourMin + ")");
        System.out.println("Production maximale: " + max + " (jour " + jourMax + ")");
        
        // 4. Écart-type (mesure de variabilité)
        double sommesCarresEcarts = 0;
        for (int prod : productionJournaliere) {
            double ecart = prod - moyenne;
            sommesCarresEcarts += ecart * ecart;
        }
        double ecartType = Math.sqrt(sommesCarresEcarts / productionJournaliere.length);
        System.out.printf("Écart-type: %.2f%n", ecartType);
        
        // 5. Jours sous la moyenne
        int joursSousMoyenne = 0;
        for (int prod : productionJournaliere) {
            if (prod < moyenne) {
                joursSousMoyenne++;
            }
        }
        System.out.println();
        System.out.println("Jours sous la moyenne: " + joursSousMoyenne + "/" + 
                          productionJournaliere.length);
        
        // 6. Analyse par semaine
        System.out.println();
        System.out.println("=== PRODUCTION PAR SEMAINE ===");
        
        for (int semaine = 0; semaine < 6; semaine++) {
            int debutSemaine = semaine * 5;
            int finSemaine = Math.min(debutSemaine + 5, productionJournaliere.length);
            
            int totalSemaine = 0;
            for (int i = debutSemaine; i < finSemaine; i++) {
                totalSemaine += productionJournaliere[i];
            }
            
            double moyenneSemaine = (double) totalSemaine / (finSemaine - debutSemaine);
            System.out.printf("Semaine %d: %d unités (moy: %.2f)%n", 
                            semaine + 1, totalSemaine, moyenneSemaine);
        }
        
        // 7. Tendance (croissante ou décroissante)
        int premiereSemaine = 0;
        for (int i = 0; i < 5; i++) {
            premiereSemaine += productionJournaliere[i];
        }
        
        int derniereSemaine = 0;
        for (int i = 25; i < 30; i++) {
            derniereSemaine += productionJournaliere[i];
        }
        
        System.out.println();
        if (derniereSemaine > premiereSemaine) {
            double augmentation = ((double)(derniereSemaine - premiereSemaine) / premiereSemaine) * 100;
            System.out.printf("Tendance: CROISSANTE (+%.1f%%)%n", augmentation);
        } else if (derniereSemaine < premiereSemaine) {
            double diminution = ((double)(premiereSemaine - derniereSemaine) / premiereSemaine) * 100;
            System.out.printf("Tendance: DÉCROISSANTE (-%.1f%%)%n", diminution);
        } else {
            System.out.println("Tendance: STABLE");
        }
        
        // 8. Production triée (pour analyse des percentiles)
        int[] productionTriee = Arrays.copyOf(productionJournaliere, productionJournaliere.length);
        Arrays.sort(productionTriee);
        
        int mediane = productionTriee[productionTriee.length / 2];
        System.out.println("Médiane: " + mediane);
    }
}