Java
Programming
Coding
Set Operations
Data Structures

Something like 'contains any' for Java set?

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Java's Set interface does not have a built-in method literally named containsAny, but the operation is still simple. The question is really: do these two collections share at least one element? In Java, the cleanest answers are usually !Collections.disjoint(...), a short loop with early return, or a stream-based check when readability matters more than minimal overhead.

The Simplest Standard-Library Answer

The standard library already exposes the inverse operation: Collections.disjoint(a, b) returns true when two collections have no elements in common.

So a practical containsAny check is:

java
1import java.util.Collections;
2import java.util.Set;
3
4public class ContainsAnyDemo {
5    public static void main(String[] args) {
6        Set<Integer> left = Set.of(1, 2, 3, 4);
7        Set<Integer> right = Set.of(4, 9, 10);
8
9        boolean containsAny = !Collections.disjoint(left, right);
10        System.out.println(containsAny);
11    }
12}

This is usually the best first answer because it is concise, standard, and immediately communicates intent.

Why a Manual Loop Is Still Useful

Sometimes you want the logic to be explicit, or you know one side is a HashSet and want to iterate over the smaller input with early exit.

java
1import java.util.Set;
2
3public class ManualContainsAny {
4    static <T> boolean containsAny(Set<T> set, Iterable<T> candidates) {
5        for (T value : candidates) {
6            if (set.contains(value)) {
7                return true;
8            }
9        }
10        return false;
11    }
12
13    public static void main(String[] args) {
14        Set<String> allowed = Set.of("read", "write", "admin");
15        System.out.println(containsAny(allowed, Set.of("guest", "write")));
16    }
17}

This version has two advantages:

  • it exits immediately on the first match
  • it lets you control which collection drives the iteration

That second point can matter for performance if one collection is much smaller than the other.

Stream API Version

If your codebase leans on streams, anyMatch is a natural translation:

java
1import java.util.Set;
2
3public class StreamContainsAny {
4    public static void main(String[] args) {
5        Set<Integer> left = Set.of(1, 2, 3, 4);
6        Set<Integer> right = Set.of(7, 8, 4);
7
8        boolean containsAny = right.stream().anyMatch(left::contains);
9        System.out.println(containsAny);
10    }
11}

This reads well, especially in data-processing code, but it does not fundamentally do anything magical. It is still checking membership one value at a time.

Choose the Iteration Direction Deliberately

If both inputs are sets, the asymptotic idea is simple: iterate over the smaller set and call contains on the larger set.

java
1import java.util.Set;
2
3public class SizeAwareContainsAny {
4    static <T> boolean containsAny(Set<T> a, Set<T> b) {
5        Set<T> smaller = a.size() <= b.size() ? a : b;
6        Set<T> larger = a.size() <= b.size() ? b : a;
7
8        for (T value : smaller) {
9            if (larger.contains(value)) {
10                return true;
11            }
12        }
13        return false;
14    }
15}

With hash-based sets, this is usually close to optimal in practice.

When retainAll Is the Wrong Tool

Some developers reach for intersection logic:

java
Set<Integer> copy = new java.util.HashSet<>(left);
copy.retainAll(right);
boolean containsAny = !copy.isEmpty();

This works, but it is often heavier than necessary because:

  • it allocates a copy
  • it may process more elements than needed
  • it expresses "build the intersection" when the real need is only "does any overlap exist"

Use retainAll when you actually need the intersection set. If you only need a boolean, prefer disjoint, a loop, or anyMatch.

Null and Collection-Type Considerations

A Set can usually answer contains efficiently, but if the other side is a list or any generic iterable, you still have good options. The normal rule is:

  • keep the hash-based membership test on the set side
  • iterate over the other collection once

Also decide how your API treats null inputs. In production code, a helper should either reject them clearly or document how they are interpreted.

A Small Utility Method for Reuse

If the check appears repeatedly, wrap it in a helper and keep the semantics in one place.

java
1import java.util.Collection;
2import java.util.Collections;
3import java.util.Objects;
4
5public final class SetUtils {
6    private SetUtils() {}
7
8    public static <T> boolean containsAny(Collection<T> left, Collection<T> right) {
9        Objects.requireNonNull(left);
10        Objects.requireNonNull(right);
11        return !Collections.disjoint(left, right);
12    }
13}

This keeps call sites readable and prevents every module from inventing its own variation.

Common Pitfalls

The biggest mistake is building a full intersection set when you only need a boolean result.

Another mistake is ignoring collection size. If you can iterate over the smaller collection and test membership in the larger set, do that.

Developers also sometimes use streams for everything even when a small loop is clearer in the local context.

Finally, do not assume a method named containsAny exists on Set itself. The operation exists conceptually, but you express it through other APIs.

Summary

  • Java Set has no method literally named containsAny.
  • The clean standard-library answer is !Collections.disjoint(a, b).
  • A manual loop or anyMatch is also fine, especially when you want explicit control.
  • Iterate over the smaller collection when performance matters.
  • Use retainAll only when you need the actual intersection, not just a boolean.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.