杰瑞科技汇

Java containsAll()方法如何高效使用?

Of course! The concept of "contains all" in Java is most commonly associated with checking if one collection contains all the elements of another. This is a fundamental operation for working with sets, lists, and other data structures.

Java containsAll()方法如何高效使用?-图1
(图片来源网络,侵删)

Here’s a complete guide covering the different ways to achieve this, from the most common to more advanced scenarios.

The Primary Method: Collection.containsAll()

This is the most direct and idiomatic way to perform a "contains all" check in Java. It's a method defined in the java.util.Collection interface, so it's available for most collection types like ArrayList, HashSet, LinkedList, etc.

Syntax

boolean containsAll(Collection<?> c)
  • Returns: true if this collection contains all of the elements in the specified collection c. Otherwise, returns false.
  • Important: The collection you pass in (c) can be of any type, but it must not contain null elements if the calling collection does not allow nulls. If c contains null and the calling collection does not, a NullPointerException will be thrown.

How it Works

The method iterates through every element in the collection c and checks if the calling collection contains it. If it finds even a single element that is not present, it immediately returns false. If it successfully finds all elements, it returns true.


Practical Examples

Let's see how to use containsAll() with different collection types.

Java containsAll()方法如何高效使用?-图2
(图片来源网络,侵删)

Example 1: Using ArrayList (List)

This is a very common scenario. Note that for lists, order doesn't matter for containsAll(), only the presence of elements.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ContainsAllExample {
    public static void main(String[] args) {
        // Our main list of ingredients
        List<String> kitchenPantry = new ArrayList<>(Arrays.asList("Flour", "Sugar", "Eggs", "Butter", "Salt"));
        // A list of ingredients for a cake
        List<String> cakeIngredients = new ArrayList<>(Arrays.asList("Flour", "Sugar", "Eggs", "Butter"));
        // Check if the pantry has all ingredients for the cake
        boolean hasAllForCake = kitchenPantry.containsAll(cakeIngredients);
        System.out.println("Kitchen Pantry: " + kitchenPantry);
        System.out.println("Cake Ingredients: " + cakeIngredients);
        System.out.println("Does the pantry have all ingredients for the cake? " + hasAllForCake); // Output: true
        // A list of ingredients for cookies (we are missing Vanilla)
        List<String> cookieIngredients = new ArrayList<>(Arrays.asList("Flour", "Sugar", "Butter", "Vanilla"));
        boolean hasAllForCookies = kitchenPantry.containsAll(cookieIngredients);
        System.out.println("\nCookie Ingredients: " + cookieIngredients);
        System.out.println("Does the pantry have all ingredients for the cookies? " + hasAllForCookies); // Output: false
    }
}

Example 2: Using HashSet (Set)

Using a HashSet is often more efficient for this operation, especially for large collections, because checking for an element's existence (contains()) is, on average, an O(1) operation, compared to O(n) for an ArrayList.

import java.util.HashSet;
import java.util.Arrays;
import java.util.Set;
public class ContainsAllSetExample {
    public static void main(String[] args) {
        Set<Integer> winningNumbers = new HashSet<>(Arrays.asList(12, 5, 8, 23, 42));
        Set<Integer> myTicket = new HashSet<>(Arrays.asList(5, 8, 12, 23, 42));
        boolean isWinner = winningNumbers.containsAll(myTicket);
        System.out.println("Winning Numbers: " + winningNumbers);
        System.out.println("My Ticket: " + myTicket);
        System.out.println("Is this a winning ticket? " + isWinner); // Output: true
        Set<Integer> mySecondTicket = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
        boolean isSecondWinner = winningNumbers.containsAll(mySecondTicket);
        System.out.println("\nMy Second Ticket: " + mySecondTicket);
        System.out.println("Is this a winning ticket? " + isSecondWinner); // Output: false
    }
}

Performance Considerations

The performance of containsAll() depends heavily on the type of collection you are calling it on.

Collection Type contains() Complexity containsAll() Complexity (for n elements in c) Notes
ArrayList, LinkedList O(n) O(m * n) m is the size of the calling list, n is the size of the passed-in list. This can be slow for large lists.
HashSet, LinkedHashSet O(1) (average) O(n) n is the size of the passed-in collection. This is very fast and generally the preferred choice for this operation.
TreeSet O(log m) O(n log m) m is the size of the TreeSet, n is the size of the passed-in collection. Efficient for sorted data.

Conclusion: If you frequently need to check if one collection contains all elements of another, using a HashSet for both collections will give you the best performance.

Java containsAll()方法如何高效使用?-图3
(图片来源网络,侵删)

Alternatives (When containsAll() isn't suitable)

Alternative 1: Using Java 8 Streams

You can achieve the same result using a Stream. This approach is more flexible if you need to perform other transformations or checks at the same time.

import java.util.List;
import java.util.Arrays;
public class ContainsAllStreamExample {
    public static void main(String[] args) {
        List<String> kitchenPantry = Arrays.asList("Flour", "Sugar", "Eggs", "Butter", "Salt");
        List<String> cakeIngredients = Arrays.asList("Flour", "Sugar", "Eggs", "Butter");
        // Using Stream.allMatch()
        boolean hasAllForCake = cakeIngredients.stream()
                                                .allMatch(kitchenPantry::contains);
        System.out.println("Does the pantry have all ingredients for the cake (using Stream)? " + hasAllForCake); // Output: true
    }
}
  • How it works: cakeIngredients.stream() creates a stream of its elements. .allMatch(kitchenPantry::contains) checks if every element in the stream satisfies the condition kitchenPantry.contains(element). The method kitchenPantry::contains is a method reference, a shorthand for the lambda element -> kitchenPantry.contains(element).

Alternative 2: For Primitive Arrays

If you are working with primitive arrays (like int[]), you cannot use containsAll() directly. You must first convert one array to a collection or use a manual loop.

Option A: Convert to a Collection (Recommended)

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class ArrayContainsAll {
    public static void main(String[] args) {
        int[] mainArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        int[] valuesToCheck = {3, 5, 7, 9};
        // Convert the main array to a Set for efficient lookups
        Set<Integer> mainSet = new HashSet<>();
        for (int value : mainArray) {
            mainSet.add(value);
        }
        // Check if all elements in the valuesToCheck array are in the set
        boolean allPresent = true;
        for (int value : valuesToCheck) {
            if (!mainSet.contains(value)) {
                allPresent = false;
                break; // Found one that's missing, no need to check further
            }
        }
        System.out.println("Main Array: " + Arrays.toString(mainArray));
        System.out.println("Values to Check: " + Arrays.toString(valuesToCheck));
        System.out.println("Does main array contain all values? " + allPresent); // Output: true
    }
}

Summary: Which one should you use?

Scenario Recommended Method Why?
General purpose collection1.containsAll(collection2) It's the standard, idiomatic, and most readable way.
Large collections, best performance Use HashSet and then containsAll() HashSet provides O(1) average time complexity for contains(), making the overall operation O(n).
Need additional stream processing collection2.stream().allMatch(collection1::contains) Offers flexibility within the Stream API for more complex logic.
Working with primitive arrays Convert one array to a Set and loop through the other. Set provides fast lookups, and the loop is straightforward for arrays.
分享:
扫描分享到社交APP
上一篇
下一篇