Cómo comprobar si una lista contiene todos los elementos de otra lista en Java

JavaJavaBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, aprenderás cómo verificar si una lista contiene todos los elementos de otra lista en Java. Esta es una tarea fundamental cuando se trabaja con colecciones y se entienden las relaciones entre conjuntos de datos.

Exploraremos el eficiente método containsAll() proporcionado por el marco de colecciones de Java para una comprobación rápida de subconjuntos. Para consolidar tu comprensión, también aprenderás cómo realizar esta comprobación manualmente utilizando un bucle. Finalmente, probaremos el comportamiento de estos métodos con casos extremos, incluyendo listas vacías y nulas, para garantizar un código robusto.


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{{"Cómo comprobar si una lista contiene todos los elementos de otra lista en Java"}} java/arrays_methods -.-> lab-559946{{"Cómo comprobar si una lista contiene todos los elementos de otra lista en Java"}} java/collections_methods -.-> lab-559946{{"Cómo comprobar si una lista contiene todos los elementos de otra lista en Java"}} java/classes_objects -.-> lab-559946{{"Cómo comprobar si una lista contiene todos los elementos de otra lista en Java"}} java/arraylist -.-> lab-559946{{"Cómo comprobar si una lista contiene todos los elementos de otra lista en Java"}} end

Usar containsAll() para la comprobación de subconjuntos

En este paso, exploraremos cómo verificar si una lista es un subconjunto de otra utilizando el método containsAll() en Java. Esta es una tarea común cuando se trabaja con colecciones, y containsAll() proporciona una forma conveniente de realizar esta comprobación.

Primero, creemos un nuevo archivo Java llamado SubsetCheck.java en tu directorio ~/project. Puedes hacer esto utilizando el explorador de archivos del WebIDE en el lado izquierdo. Haz clic derecho en el área ~/project, selecciona "Nuevo archivo" y escribe SubsetCheck.java.

Ahora, abre el archivo SubsetCheck.java en el editor y agrega el siguiente código:

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);
    }
}

Desglosemos el código:

  • Importamos ArrayList y List del paquete java.util para trabajar con listas.
  • Creamos dos objetos ArrayList: mainList y subList.
  • Agregamos algunos elementos de tipo cadena a ambas listas.
  • La parte clave es mainList.containsAll(subList). Este método verifica si mainList contiene todos los elementos presentes en subList. Devuelve true si es así, y false en caso contrario.
  • Almacenamos el resultado en una variable booleana isSubset y lo imprimimos.
  • Luego creamos anotherList que contiene un elemento que no está presente en mainList y realizamos la misma comprobación para ver el resultado cuando no es un subconjunto.

Guarda el archivo SubsetCheck.java (Ctrl+S o Cmd+S).

Ahora, abre la Terminal en la parte inferior del WebIDE. Asegúrate de estar en el directorio ~/project. Si no lo estás, utiliza el comando cd ~/project.

Compila el código Java utilizando el comando javac:

javac SubsetCheck.java

Si no hay errores de compilación, deberías ver un archivo SubsetCheck.class creado en el directorio ~/project.

Finalmente, ejecuta el programa Java compilado utilizando el comando java:

java SubsetCheck

Deberías ver una salida similar a esta:

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

Esta salida confirma que subList es de hecho un subconjunto de mainList porque todos sus elementos están presentes en mainList, mientras que anotherList no es un subconjunto porque "Grape" no está en mainList.

Verificar con un bucle manual

En el paso anterior, utilizamos el conveniente método containsAll() para comprobar si una lista es un subconjunto de otra. Si bien containsAll() es eficiente, es útil entender cómo se realizaría esta comprobación manualmente utilizando un bucle. Esto profundizará tu comprensión de cómo funcionan internamente los métodos de las colecciones.

Vamos a agregar un nuevo método a nuestro archivo SubsetCheck.java para realizar la comprobación de subconjunto manualmente. Abre ~/project/SubsetCheck.java en el editor del WebIDE.

Agrega el siguiente método dentro de la clase SubsetCheck, pero fuera del método 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;
    }

Este nuevo método isSubsetManual toma dos listas como entrada. Luego recorre cada element en la subList. Dentro del bucle, verifica si la mainList contiene el element actual utilizando el método contains(). Si encuentra incluso un elemento en subList que no está en mainList, inmediatamente sabe que subList no es un subconjunto y devuelve false. Si el bucle finaliza sin encontrar ningún elemento en subList que falte en mainList, significa que todos los elementos están presentes y el método devuelve true.

Ahora, llamemos a este nuevo método desde nuestro método main para comparar su resultado con containsAll(). Modifica el método main en SubsetCheck.java para incluir llamadas a 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;
    }
}

Guarda el archivo SubsetCheck.java modificado.

Ahora, compila el código actualizado en la Terminal:

javac SubsetCheck.java

Y ejecuta el programa nuevamente:

java SubsetCheck

Deberías ver una salida similar a esta, que muestra que tanto el método containsAll() como nuestro método de bucle manual producen los mismos resultados:

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

Este paso demuestra que se puede lograr el mismo resultado que con containsAll() recorriendo el posible subconjunto y comprobando la presencia de cada elemento en la lista principal. Si bien containsAll() es generalmente preferido por su concisión y posibles optimizaciones de rendimiento en la biblioteca de Java, entender el enfoque manual es valioso para el aprendizaje.

Probar con listas vacías y nulas

En este paso, exploraremos cómo se comportan el método containsAll() y nuestro método de comprobación manual cuando se tratan con listas vacías y valores null. Comprender estos casos extremos es importante para escribir código robusto.

Abre el archivo ~/project/SubsetCheck.java en el editor del WebIDE. Agregaremos más casos de prueba al método main.

Modifica el método main para incluir comprobaciones con listas vacías y una lista 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;
    }
}

Hemos agregado secciones para probar con una emptyList (lista vacía) y una nullList (lista nula). Observa que para las pruebas con nullList, envolvemos las llamadas en bloques try-catch. Esto se debe a que intentar llamar a métodos en un objeto null (como mainList.containsAll(nullList)) resultará en una NullPointerException. Nuestro método manual también debe manejar el caso en el que la subList sea null, por lo que agregamos una comprobación al principio de isSubsetManual.

Guarda el archivo SubsetCheck.java modificado.

Compila el código actualizado en la Terminal:

javac SubsetCheck.java

Y ejecuta el programa nuevamente:

java SubsetCheck

Deberías ver una salida similar a esta:

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.

A partir de la salida, observa lo siguiente:

  • Una lista vacía se considera un subconjunto de cualquier lista (incluida otra lista vacía). Tanto containsAll() como nuestro método manual identifican correctamente esto.
  • Una lista no vacía no es un subconjunto de una lista vacía.
  • Pasar una lista null a containsAll() o a nuestro método manual (sin una comprobación de nulo) resulta en una NullPointerException. Esto destaca la importancia de manejar los posibles valores null en tu código.

Este paso concluye nuestra exploración de la comprobación de subconjuntos en listas de Java. Has aprendido cómo usar el método incorporado containsAll(), cómo realizar la comprobación manualmente y cómo se comportan estos métodos con listas vacías y nulas.

Resumen

En este laboratorio, aprendimos cómo comprobar si una lista contiene todos los elementos de otra lista en Java. Nos centramos principalmente en utilizar el conveniente método containsAll() proporcionado por la interfaz Collection.

Demostramos cómo usar containsAll() con listas de ejemplo y observamos su comportamiento tanto en casos de subconjunto como en casos de no subconjunto. Este método ofrece una forma concisa y eficiente de realizar esta tarea común de comparación de listas.