How to Check If a List Contains All Elements of Another List in Java

JavaJavaBeginner
Practice Now

Introduction

In this lab, you will learn how to check if one list contains all elements of another list in Java. This is a fundamental task when working with collections and understanding relationships between data sets.

We will explore the efficient containsAll() method provided by the Java Collections framework for a quick subset check. To solidify your understanding, you will also learn how to perform this check manually using a loop. Finally, we will test the behavior of these methods with edge cases, including empty and null lists, to ensure robust code.


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{{"How to Check If a List Contains All Elements of Another List in Java"}} java/arrays_methods -.-> lab-559946{{"How to Check If a List Contains All Elements of Another List in Java"}} java/collections_methods -.-> lab-559946{{"How to Check If a List Contains All Elements of Another List in Java"}} java/classes_objects -.-> lab-559946{{"How to Check If a List Contains All Elements of Another List in Java"}} java/arraylist -.-> lab-559946{{"How to Check If a List Contains All Elements of Another List in Java"}} end

Use containsAll() for Subset Check

In this step, we will explore how to check if one list is a subset of another using the containsAll() method in Java. This is a common task when working with collections, and containsAll() provides a convenient way to perform this check.

First, let's create a new Java file named SubsetCheck.java in your ~/project directory. You can do this using the WebIDE file explorer on the left. Right-click in the ~/project area, select "New File", and type SubsetCheck.java.

Now, open the SubsetCheck.java file in the editor and add the following code:

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

Let's break down the code:

  • We import ArrayList and List from the java.util package to work with lists.
  • We create two ArrayList objects: mainList and subList.
  • We add some string elements to both lists.
  • The key part is mainList.containsAll(subList). This method checks if mainList contains all the elements present in subList. It returns true if it does, and false otherwise.
  • We store the result in a boolean variable isSubset and print it.
  • We then create anotherList which contains an element not present in mainList and perform the same check to see the result when it's not a subset.

Save the SubsetCheck.java file (Ctrl+S or Cmd+S).

Now, open the Terminal at the bottom of the WebIDE. Make sure you are in the ~/project directory. If not, use the command cd ~/project.

Compile the Java code using the javac command:

javac SubsetCheck.java

If there are no compilation errors, you should see a SubsetCheck.class file created in the ~/project directory.

Finally, run the compiled Java program using the java command:

java SubsetCheck

You should see output similar to this:

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

This output confirms that subList is indeed a subset of mainList because all its elements are present in mainList, while anotherList is not a subset because "Grape" is not in mainList.

Verify with Manual Loop

In the previous step, we used the convenient containsAll() method to check for a subset. While containsAll() is efficient, it's helpful to understand how you would perform this check manually using a loop. This will deepen your understanding of how collection methods might work internally.

Let's add a new method to our SubsetCheck.java file to perform the subset check manually. Open ~/project/SubsetCheck.java in the WebIDE editor.

Add the following method inside the SubsetCheck class, but outside the main method:

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

This new method isSubsetManual takes two lists as input. It then loops through each element in the subList. Inside the loop, it checks if the mainList contains the current element using the contains() method. If it finds even one element in subList that is not in mainList, it immediately knows that subList is not a subset and returns false. If the loop finishes without finding any element in subList that is missing from mainList, it means all elements are present, and the method returns true.

Now, let's call this new method from our main method to compare its result with containsAll(). Modify the main method in SubsetCheck.java to include calls to 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;
    }
}

Save the modified SubsetCheck.java file.

Now, compile the updated code in the Terminal:

javac SubsetCheck.java

And run the program again:

java SubsetCheck

You should see output similar to this, showing that both the containsAll() method and our manual loop method produce the same results:

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

This step demonstrates that you can achieve the same result as containsAll() by iterating through the potential subset and checking for the presence of each element in the main list. While containsAll() is generally preferred for its conciseness and potential performance optimizations in the Java library, understanding the manual approach is valuable for learning.

Test with Empty and Null Lists

In this step, we will explore how the containsAll() method and our manual check method behave when dealing with empty lists and null values. Understanding these edge cases is important for writing robust code.

Open the ~/project/SubsetCheck.java file in the WebIDE editor. We will add more test cases to the main method.

Modify the main method to include checks with empty lists and a null list:

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

We've added sections to test with an emptyList and a nullList. Notice that for the nullList tests, we wrap the calls in try-catch blocks. This is because attempting to call methods on a null object (like mainList.containsAll(nullList)) will result in a NullPointerException. Our manual method also needs to handle the case where the subList is null, so we added a check at the beginning of isSubsetManual.

Save the modified SubsetCheck.java file.

Compile the updated code in the Terminal:

javac SubsetCheck.java

And run the program again:

java SubsetCheck

You should see output similar to this:

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.

From the output, observe the following:

  • An empty list is considered a subset of any list (including another empty list). Both containsAll() and our manual method correctly identify this.
  • A non-empty list is not a subset of an empty list.
  • Passing a null list to containsAll() or our manual method (without a null check) results in a NullPointerException. This highlights the importance of handling potential null values in your code.

This step concludes our exploration of checking for subsets in Java lists. You've learned how to use the built-in containsAll() method, how to perform the check manually, and how these methods behave with empty and null lists.

Summary

In this lab, we learned how to check if one list contains all elements of another list in Java. We primarily focused on using the convenient containsAll() method provided by the Collection interface.

We demonstrated how to use containsAll() with example lists and observed its behavior for both subset and non-subset cases. This method offers a concise and efficient way to perform this common list comparison task.