Comment vérifier si une liste contient tous les éléments d'une autre liste en Java

JavaJavaBeginner
Pratiquer maintenant

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Dans ce laboratoire (lab), vous apprendrez à vérifier si une liste contient tous les éléments d'une autre liste en Java. Il s'agit d'une tâche fondamentale lorsqu'on travaille avec des collections et qu'on cherche à comprendre les relations entre des ensembles de données.

Nous allons explorer la méthode efficace containsAll() fournie par le framework Java Collections pour effectuer rapidement un test de sous-ensemble. Pour consolider votre compréhension, vous apprendrez également à effectuer ce test manuellement en utilisant une boucle. Enfin, nous testerons le comportement de ces méthodes avec des cas limites, y compris des listes vides et null, pour garantir un code robuste.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("Java")) -.-> java/BasicSyntaxGroup(["Basic Syntax"]) java(("Java")) -.-> java/DataStructuresGroup(["Data Structures"]) java(("Java")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["Object-Oriented and Advanced Concepts"]) java/BasicSyntaxGroup -.-> java/for_loop("For Loop") java/DataStructuresGroup -.-> java/arrays_methods("Arrays Methods") java/DataStructuresGroup -.-> java/collections_methods("Collections Methods") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/classes_objects("Classes/Objects") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/arraylist("ArrayList") subgraph Lab Skills java/for_loop -.-> lab-559946{{"Comment vérifier si une liste contient tous les éléments d'une autre liste en Java"}} java/arrays_methods -.-> lab-559946{{"Comment vérifier si une liste contient tous les éléments d'une autre liste en Java"}} java/collections_methods -.-> lab-559946{{"Comment vérifier si une liste contient tous les éléments d'une autre liste en Java"}} java/classes_objects -.-> lab-559946{{"Comment vérifier si une liste contient tous les éléments d'une autre liste en Java"}} java/arraylist -.-> lab-559946{{"Comment vérifier si une liste contient tous les éléments d'une autre liste en Java"}} end

Utiliser containsAll() pour vérifier un sous-ensemble

Dans cette étape, nous allons explorer comment vérifier si une liste est un sous-ensemble d'une autre en utilisant la méthode containsAll() en Java. Il s'agit d'une tâche courante lorsqu'on travaille avec des collections, et containsAll() offre un moyen pratique d'effectuer cette vérification.

Tout d'abord, créons un nouveau fichier Java nommé SubsetCheck.java dans votre répertoire ~/project. Vous pouvez le faire en utilisant l'explorateur de fichiers de l'WebIDE à gauche. Cliquez avec le bouton droit dans la zone ~/project, sélectionnez "Nouveau fichier" et tapez SubsetCheck.java.

Maintenant, ouvrez le fichier SubsetCheck.java dans l'éditeur et ajoutez le code suivant :

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

public class SubsetCheck {

    public static void main(String[] args) {
        // Create the main list
        List<String> mainList = new ArrayList<>();
        mainList.add("Apple");
        mainList.add("Banana");
        mainList.add("Cherry");
        mainList.add("Date");

        // Create a potential subset list
        List<String> subList = new ArrayList<>();
        subList.add("Banana");
        subList.add("Cherry");

        // Check if subList is a subset of mainList using containsAll()
        boolean isSubset = mainList.containsAll(subList);

        // Print the result
        System.out.println("Main List: " + mainList);
        System.out.println("Sub List: " + subList);
        System.out.println("Is subList a subset of mainList? " + isSubset);

        // Create another list that is not a subset
        List<String> anotherList = new ArrayList<>();
        anotherList.add("Banana");
        anotherList.add("Grape"); // Grape is not in mainList

        // Check if anotherList is a subset of mainList
        boolean isAnotherSubset = mainList.containsAll(anotherList);

        // Print the result for the second check
        System.out.println("\nAnother List: " + anotherList);
        System.out.println("Is anotherList a subset of mainList? " + isAnotherSubset);
    }
}

Analysons le code :

  • Nous importons ArrayList et List du package java.util pour travailler avec des listes.
  • Nous créons deux objets ArrayList : mainList et subList.
  • Nous ajoutons quelques éléments de type chaîne de caractères à ces deux listes.
  • La partie clé est mainList.containsAll(subList). Cette méthode vérifie si mainList contient tous les éléments présents dans subList. Elle retourne true si c'est le cas, et false sinon.
  • Nous stockons le résultat dans une variable booléenne isSubset et l'affichons.
  • Nous créons ensuite anotherList qui contient un élément absent de mainList et effectuons la même vérification pour voir le résultat lorsque ce n'est pas un sous-ensemble.

Enregistrez le fichier SubsetCheck.java (Ctrl+S ou Cmd+S).

Maintenant, ouvrez le Terminal en bas de l'WebIDE. Assurez-vous d'être dans le répertoire ~/project. Sinon, utilisez la commande cd ~/project.

Compilez le code Java en utilisant la commande javac :

javac SubsetCheck.java

S'il n'y a pas d'erreurs de compilation, vous devriez voir un fichier SubsetCheck.class créé dans le répertoire ~/project.

Enfin, exécutez le programme Java compilé en utilisant la commande java :

java SubsetCheck

Vous devriez voir une sortie similaire à ceci :

Main List: [Apple, Banana, Cherry, Date]
Sub List: [Banana, Cherry]
Is subList a subset of mainList? true

Another List: [Banana, Grape]
Is anotherList a subset of mainList? false

Cette sortie confirme que subList est effectivement un sous-ensemble de mainList car tous ses éléments sont présents dans mainList, tandis que anotherList n'est pas un sous-ensemble car "Grape" n'est pas dans mainList.

Vérification avec une boucle manuelle

Dans l'étape précédente, nous avons utilisé la pratique méthode containsAll() pour vérifier si une liste est un sous-ensemble d'une autre. Bien que containsAll() soit efficace, il est utile de comprendre comment effectuer cette vérification manuellement en utilisant une boucle. Cela approfondira votre compréhension du fonctionnement interne des méthodes de collection.

Ajoutons une nouvelle méthode à notre fichier SubsetCheck.java pour effectuer la vérification de sous-ensemble manuellement. Ouvrez ~/project/SubsetCheck.java dans l'éditeur de l'WebIDE.

Ajoutez la méthode suivante à l'intérieur de la classe SubsetCheck, mais en dehors de la méthode main :

    // Method to manually check if subList is a subset of mainList
    public static boolean isSubsetManual(List<String> mainList, List<String> subList) {
        // Iterate through each element in the subList
        for (String element : subList) {
            // If the mainList does NOT contain the current element from subList,
            // then subList is not a subset, and we can return false immediately.
            if (!mainList.contains(element)) {
                return false;
            }
        }
        // If we have checked all elements in subList and found them all in mainList,
        // then subList is a subset.
        return true;
    }

Cette nouvelle méthode isSubsetManual prend deux listes en entrée. Elle parcourt ensuite chaque élément de la subList. À l'intérieur de la boucle, elle vérifie si la mainList contient l'élément actuel en utilisant la méthode contains(). Si elle trouve même un seul élément de la subList qui n'est pas dans la mainList, elle sait immédiatement que la subList n'est pas un sous-ensemble et retourne false. Si la boucle se termine sans trouver d'élément de la subList manquant dans la mainList, cela signifie que tous les éléments sont présents, et la méthode retourne true.

Maintenant, appelons cette nouvelle méthode depuis notre méthode main pour comparer son résultat avec celui de containsAll(). Modifiez la méthode main dans SubsetCheck.java pour inclure des appels à isSubsetManual :

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

public class SubsetCheck {

    public static void main(String[] args) {
        // Create the main list
        List<String> mainList = new ArrayList<>();
        mainList.add("Apple");
        mainList.add("Banana");
        mainList.add("Cherry");
        mainList.add("Date");

        // Create a potential subset list
        List<String> subList = new ArrayList<>();
        subList.add("Banana");
        subList.add("Cherry");

        // Check if subList is a subset of mainList using containsAll()
        boolean isSubsetContainsAll = mainList.containsAll(subList);
        // Check if subList is a subset of mainList using manual loop
        boolean isSubsetManualCheck = isSubsetManual(mainList, subList);


        // Print the result
        System.out.println("Main List: " + mainList);
        System.out.println("Sub List: " + subList);
        System.out.println("Is subList a subset of mainList (containsAll)? " + isSubsetContainsAll);
        System.out.println("Is subList a subset of mainList (manual check)? " + isSubsetManualCheck);


        // Create another list that is not a subset
        List<String> anotherList = new ArrayList<>();
        anotherList.add("Banana");
        anotherList.add("Grape"); // Grape is not in mainList

        // Check if anotherList is a subset of mainList using containsAll()
        boolean isAnotherSubsetContainsAll = mainList.containsAll(anotherList);
         // Check if anotherList is a subset of mainList using manual loop
        boolean isAnotherSubsetManualCheck = isSubsetManual(mainList, anotherList);


        // Print the result for the second check
        System.out.println("\nAnother List: " + anotherList);
        System.out.println("Is anotherList a subset of mainList (containsAll)? " + isAnotherSubsetContainsAll);
        System.out.println("Is anotherList a subset of mainList (manual check)? " + isAnotherSubsetManualCheck);

    }

    // Method to manually check if subList is a subset of mainList
    public static boolean isSubsetManual(List<String> mainList, List<String> subList) {
        // Iterate through each element in the subList
        for (String element : subList) {
            // If the mainList does NOT contain the current element from subList,
            // then subList is not a subset, and we can return false immediately.
            if (!mainList.contains(element)) {
                return false;
            }
        }
        // If we have checked all elements in subList and found them all in mainList,
        // then subList is a subset.
        return true;
    }
}

Enregistrez le fichier SubsetCheck.java modifié.

Maintenant, compilez le code mis à jour dans le Terminal :

javac SubsetCheck.java

Et exécutez le programme à nouveau :

java SubsetCheck

Vous devriez voir une sortie similaire à ceci, montrant que la méthode containsAll() et notre méthode de boucle manuelle produisent les mêmes résultats :

Main List: [Apple, Banana, Cherry, Date]
Sub List: [Banana, Cherry]
Is subList a subset of mainList (containsAll)? true
Is subList a subset of mainList (manual check)? true

Another List: [Banana, Grape]
Is anotherList a subset of mainList (containsAll)? false
Is anotherList a subset of mainList (manual check)? false

Cette étape démontre que vous pouvez obtenir le même résultat que containsAll() en parcourant le potentiel sous-ensemble et en vérifiant la présence de chaque élément dans la liste principale. Bien que containsAll() soit généralement préféré pour sa concision et ses optimisations de performance potentielles dans la bibliothèque Java, comprendre l'approche manuelle est précieux pour l'apprentissage.

Test avec des listes vides et des listes null

Dans cette étape, nous allons explorer le comportement de la méthode containsAll() et de notre méthode de vérification manuelle lorsqu'elles traitent des listes vides et des valeurs null. Comprendre ces cas limites est important pour écrire un code robuste.

Ouvrez le fichier ~/project/SubsetCheck.java dans l'éditeur de l'WebIDE. Nous allons ajouter plus de cas de test à la méthode main.

Modifiez la méthode main pour inclure des vérifications avec des listes vides et une liste null :

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

public class SubsetCheck {

    public static void main(String[] args) {
        // Create the main list
        List<String> mainList = new ArrayList<>();
        mainList.add("Apple");
        mainList.add("Banana");
        mainList.add("Cherry");
        mainList.add("Date");

        // Create a potential subset list
        List<String> subList = new ArrayList<>();
        subList.add("Banana");
        subList.add("Cherry");

        // Check if subList is a subset of mainList using containsAll()
        boolean isSubsetContainsAll = mainList.containsAll(subList);
        // Check if subList is a subset of mainList using manual loop
        boolean isSubsetManualCheck = isSubsetManual(mainList, subList);


        // Print the result
        System.out.println("Main List: " + mainList);
        System.out.println("Sub List: " + subList);
        System.out.println("Is subList a subset of mainList (containsAll)? " + isSubsetContainsAll);
        System.out.println("Is subList a subset of mainList (manual check)? " + isSubsetManualCheck);


        // Create another list that is not a subset
        List<String> anotherList = new ArrayList<>();
        anotherList.add("Banana");
        anotherList.add("Grape"); // Grape is not in mainList

        // Check if anotherList is a subset of mainList using containsAll()
        boolean isAnotherSubsetContainsAll = mainList.containsAll(anotherList);
         // Check if anotherList is a subset of mainList using manual loop
        boolean isAnotherSubsetManualCheck = isSubsetManual(mainList, anotherList);


        // Print the result for the second check
        System.out.println("\nAnother List: " + anotherList);
        System.out.println("Is anotherList a subset of mainList (containsAll)? " + isAnotherSubsetContainsAll);
        System.out.println("Is anotherList a subset of mainList (manual check)? " + isAnotherSubsetManualCheck);

        // --- Test with Empty Lists ---

        // Create an empty list
        List<String> emptyList = new ArrayList<>();

        // Check if emptyList is a subset of mainList
        boolean isEmptySubsetContainsAll = mainList.containsAll(emptyList);
        boolean isEmptySubsetManualCheck = isSubsetManual(mainList, emptyList);

        System.out.println("\nEmpty List: " + emptyList);
        System.out.println("Is emptyList a subset of mainList (containsAll)? " + isEmptySubsetContainsAll);
        System.out.println("Is emptyList a subset of mainList (manual check)? " + isEmptySubsetManualCheck);

        // Check if mainList is a subset of emptyList (should be false unless mainList is also empty)
        boolean isMainSubsetEmptyContainsAll = emptyList.containsAll(mainList);
        boolean isMainSubsetEmptyManualCheck = isSubsetManual(emptyList, mainList);

        System.out.println("Is mainList a subset of emptyList (containsAll)? " + isMainSubsetEmptyContainsAll);
        System.out.println("Is mainList a subset of emptyList (manual check)? " + isMainSubsetEmptyManualCheck);

        // --- Test with Null List ---

        // Create a null list
        List<String> nullList = null;

        // Check with nullList using containsAll()
        System.out.println("\nNull List: " + nullList);
        try {
            boolean isNullSubsetContainsAll = mainList.containsAll(nullList);
            System.out.println("Is nullList a subset of mainList (containsAll)? " + isNullSubsetContainsAll);
        } catch (NullPointerException e) {
            System.out.println("Checking with nullList using containsAll() resulted in: " + e);
        }

        // Check with nullList using manual loop
         try {
            boolean isNullSubsetManualCheck = isSubsetManual(mainList, nullList);
            System.out.println("Is nullList a subset of mainList (manual check)? " + isNullSubsetManualCheck);
        } catch (NullPointerException e) {
            System.out.println("Checking with nullList using manual check resulted in: " + e);
        }
    }

    // Method to manually check if subList is a subset of mainList
    public static boolean isSubsetManual(List<String> mainList, List<String> subList) {
        // Add a check for null subList in the manual method
        if (subList == null) {
             throw new NullPointerException("Sub list cannot be null for manual check.");
        }
        // Iterate through each element in the subList
        for (String element : subList) {
            // If the mainList does NOT contain the current element from subList,
            // then subList is not a subset, and we can return false immediately.
            if (!mainList.contains(element)) {
                return false;
            }
        }
        // If we have checked all elements in subList and found them all in mainList,
        // then subList is a subset.
        return true;
    }
}

Nous avons ajouté des sections pour tester avec une emptyList (liste vide) et une nullList (liste null). Notez que pour les tests avec la nullList, nous avons enveloppé les appels dans des blocs try-catch. En effet, tenter d'appeler des méthodes sur un objet null (comme mainList.containsAll(nullList)) entraînera une NullPointerException. Notre méthode manuelle doit également gérer le cas où la subList est null, c'est pourquoi nous avons ajouté une vérification au début de isSubsetManual.

Enregistrez le fichier SubsetCheck.java modifié.

Compilez le code mis à jour dans le Terminal :

javac SubsetCheck.java

Et exécutez le programme à nouveau :

java SubsetCheck

Vous devriez voir une sortie similaire à ceci :

Main List: [Apple, Banana, Cherry, Date]
Sub List: [Banana, Cherry]
Is subList a subset of mainList (containsAll)? true
Is subList a subset of mainList (manual check)? true

Another List: [Banana, Grape]
Is anotherList a subset of mainList (containsAll)? false
Is anotherList a subset of mainList (manual check)? false

Empty List: []
Is emptyList a subset of mainList (containsAll)? true
Is emptyList a subset of mainList (manual check)? true
Is mainList a subset of emptyList (containsAll)? false
Is mainList a subset of emptyList (manual check)? false

Null List: null
Checking with nullList using containsAll() resulted in: java.lang.NullPointerException
Checking with nullList using manual check resulted in: java.lang.NullPointerException: Sub list cannot be null for manual check.

À partir de la sortie, observez les points suivants :

  • Une liste vide est considérée comme un sous-ensemble de toute liste (y compris une autre liste vide). Tant containsAll() que notre méthode manuelle identifient correctement ce cas.
  • Une liste non vide n'est pas un sous-ensemble d'une liste vide.
  • Passer une liste null à containsAll() ou à notre méthode manuelle (sans vérification de null) entraîne une NullPointerException. Cela souligne l'importance de gérer les valeurs null potentielles dans votre code.

Cette étape conclut notre exploration de la vérification de sous-ensembles dans les listes Java. Vous avez appris à utiliser la méthode intégrée containsAll(), à effectuer la vérification manuellement et à comprendre le comportement de ces méthodes avec des listes vides et des listes null.

Résumé

Dans ce laboratoire, nous avons appris à vérifier si une liste contient tous les éléments d'une autre liste en Java. Nous nous sommes principalement concentrés sur l'utilisation de la pratique méthode containsAll() fournie par l'interface Collection.

Nous avons démontré comment utiliser containsAll() avec des listes d'exemple et observé son comportement dans les cas de sous-ensemble et de non-sous-ensemble. Cette méthode offre un moyen concis et efficace d'effectuer cette tâche courante de comparaison de listes.