CodeGym /Cours /JAVA 25 SELF /Transformation des collections

Transformation des collections

JAVA 25 SELF
Niveau 28, Leçon 1
Disponible

1. Transformation des éléments des collections

En programmation, l’une des opérations les plus courantes est la transformation d’une collection : nous avons une collection de données d’un type, et sur cette base nous devons créer une nouvelle collection d’un autre type. Par exemple, à partir d’une liste d’objets de type User, obtenir la liste de leurs noms (String), ou, à partir d’une liste de nombres, la liste de leurs carrés.

La méthode la plus fondamentale et la plus claire en Java est d’utiliser une approche impérative, c’est‑à‑dire une boucle for (souvent for-each).

Exemple : obtenir la liste des longueurs à partir d’une liste de chaînes

Supposons que nous ayons une liste de noms de villes :

List<String> cities = List.of("Londres", "Paris", "Tokyo", "New York");

Notre objectif est de créer une nouvelle liste qui contiendra la longueur de chaque nom. Le résultat final doit être : [7, 5, 5, 8].

Solution avec une boucle for :

import java.util.ArrayList;
import java.util.List;

public class CollectionTransform {
    public static void main(String[] args) {
        List<String> cities = List.of("Londres", "Paris", "Tokyo", "New York");
        List<Integer> lengths = new ArrayList<>(); // Nous créons une nouvelle liste vide pour le résultat

        for (String city : cities) {
            // Pour chaque élément de cities, nous calculons sa longueur...
            int length = city.length();
            // ...et nous ajoutons ce résultat à la nouvelle liste
            lengths.add(length);
        }

        System.out.println(lengths); // Affichera: [7, 5, 5, 8]
    }
}

Nous commençons par créer une nouvelle collection vide pour les résultats — la transformation ne modifie pas la collection d’origine. Pour parcourir la collection source, nous utilisons une boucle for-each et, à l’intérieur, nous appliquons la logique nécessaire (length()) à chaque élément, puis nous ajoutons le résultat à la nouvelle liste via add.

2. Transformation d’objets

Nous travaillons souvent avec des types de données plus complexes. Supposons que nous ayons une classe Product, et qu’il faille obtenir la liste de ses noms (ou de ses prix).

public class Product {
    private String name;
    private double price;

    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public double getPrice() {
        return price;
    }
}

Maintenant, avec une liste de produits, obtenons la liste de leurs noms :

import java.util.ArrayList;
import java.util.List;

public class ProductExample {
    public static void main(String[] args) {
        List<Product> products = List.of(
            new Product("Ordinateur portable", 1200.0),
            new Product("Souris", 25.5),
            new Product("Clavier", 75.0)
        );

        // Nous créons une nouvelle liste pour les noms
        List<String> productNames = new ArrayList<>();

        for (Product product : products) {
            // Pour chaque objet Product, nous obtenons son nom
            productNames.add(product.getName());
        }

        System.out.println(productNames); // Affichera: [Ordinateur portable, Souris, Clavier]
    }
}

La logique est la même : nous itérons sur la collection source, nous appliquons à chaque élément la méthode nécessaire (par exemple, getName()) et nous ajoutons le résultat à la nouvelle collection.

3. Travailler avec des collections imbriquées

Considérons le cas d’une liste de listes : plusieurs départements, chacun avec sa propre liste d’employés. L’objectif est d’obtenir une seule liste « plate » de tous les employés.

Exemple : fusion des listes d’employés

List<List<String>> departments = List.of(
    List.of("Anna", "Boris"),
    List.of("Victoria", "Gleb", "Dmitri"),
    List.of("Elena")
);

Nous voulons obtenir une liste unique : [Anna, Boris, Victoria, Gleb, Dmitri, Elena].

Méthode 1 : au moyen de addAll()

import java.util.ArrayList;
import java.util.List;

public class NestedCollectionExample {
    public static void main(String[] args) {
        List<List<String>> departments = List.of(
            List.of("Anna", "Boris"),
            List.of("Victoria", "Gleb", "Dmitri"),
            List.of("Elena")
        );

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

        // Nous itérons sur chaque liste (département)
        for (List<String> department : departments) {
            // Nous ajoutons tous les éléments de la liste courante à la liste globale
            allEmployees.addAll(department);
        }

        System.out.println(allEmployees); // [Anna, Boris, Victoria, Gleb, Dmitri, Elena]
    }
}

Méthode 2 : boucle imbriquée — la même chose, mais « à la main » :

List<List<String>> departments = List.of(...);
List<String> allEmployees = new ArrayList<>();

for (List<String> department : departments) { // Boucle externe sur les départements
    for (String employee : department) {      // Boucle interne sur les employés
        allEmployees.add(employee);
    }
}

System.out.println(allEmployees);

Les deux approches sont équivalentes quant au résultat. La méthode addAll() encapsule en substance la logique de la boucle imbriquée et rend le code plus concis.

4. Cas complexes et transformations conditionnelles

Parfois, il faut n’appliquer la transformation qu’aux éléments qui satisfont une condition. Par exemple, obtenir la liste des noms de villes qui commencent par la lettre "N", puis prendre leur longueur. Ici, nous combinons filtrage et transformation : if + appel de méthode (length()).

import java.util.ArrayList;
import java.util.List;

public class ConditionalTransform {
    public static void main(String[] args) {
        List<String> cities = List.of("Londres", "Paris", "Tokyo", "New York", "Nuremberg");
        List<Integer> lengths = new ArrayList<>();

        for (String city : cities) {
            // D’abord, nous vérifions la condition
            if (city.startsWith("N")) {
                // Si la condition est satisfaite, nous appliquons la transformation
                lengths.add(city.length());
            }
        }

        System.out.println(lengths); // Affichera: [8, 9]
    }
}

Le schéma est le suivant : à l’intérieur de la boucle, nous filtrons d’abord l’élément au moyen d’une condition (startsWith, comparaison, test d’intervalle, etc.), puis nous appliquons la transformation voulue et plaçons le résultat dans la nouvelle liste.

5. Erreurs typiques et pièges

Erreur n° 1 : modifier la collection source pendant l’itération. Une erreur fréquente consiste à essayer d’ajouter/supprimer des éléments de la collection source directement dans une boucle for-each. Cela conduit à des erreurs et à un comportement imprévisible. Solution : créez toujours une nouvelle liste pour les résultats et remplissez‑la.

Erreur n° 2 : transtypage incorrect. Si vous travaillez avec des collections « brutes » (par exemple, via Object) et que vous convertissez des éléments vers un type erroné, vous obtiendrez une ClassCastException. Utilisez des génériques (List<T>) et respectez les signatures.

Erreur n° 3 : utilisation inefficace des ressources. Pour des collections très volumineuses, la création constante de nouvelles listes et la copie des éléments peuvent coûter en mémoire et en temps. Dans la plupart des tâches courantes, cela reste acceptable, mais pour le traitement de grands volumes de données, tenez compte de la complexité et, si nécessaire, optimisez l’approche.

1
Mission
JAVA 25 SELF, niveau 28, leçon 1
Bloqué
Création de la liste des étudiants pour l'album de promotion 🎓
Création de la liste des étudiants pour l'album de promotion 🎓
1
Mission
JAVA 25 SELF, niveau 28, leçon 1
Bloqué
Rassembler les trésors de différents coffres 💰
Rassembler les trésors de différents coffres 💰
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION