Rahul garg
Rahul garg

Reputation: 9362

Something like 'contains any' for Java set?

I have two sets, A and B, of the same type.

I have to find if A contains any element from the set B.

What would be the best way to do that without iterating over the sets? The Set library has contains(object) and containsAll(collection), but not containsAny(collection).

Upvotes: 398

Views: 196338

Answers (9)

gpl
gpl

Reputation: 2995

Stream::anyMatch

Since Java 8 you could use Stream::anyMatch.

setA.stream().anyMatch(setB::contains)

Upvotes: 273

Yamcha
Yamcha

Reputation: 1334

Apache Commons has a method CollectionUtils.containsAny().

Upvotes: 58

CaTalyst.X
CaTalyst.X

Reputation: 1665

A good way to implement containsAny for sets is using the Guava Sets.intersection().

containsAny would return a boolean, so the call looks like:

Sets.intersection(set1, set2).isEmpty()

This returns true iff the sets are disjoint, otherwise false. The time complexity of this is likely slightly better than retainAll because you dont have to do any cloning to avoid modifying your original set.

Upvotes: 41

Adam111p
Adam111p

Reputation: 3717

I use org.apache.commons.collections.CollectionUtils

CollectionUtils.containsAny(someCollection1, someCollection2)

That is All! Returns true if at least one element is in both collections.

Simple to use, and the name of the function is more suggestive.

Upvotes: 30

Frontline
Frontline

Reputation: 6745

Wouldn't Collections.disjoint(A, B) work? From the documentation:

Returns true if the two specified collections have no elements in common.

Thus, the method returns false if the collections contains any common elements.

Upvotes: 671

Plap
Plap

Reputation: 1056

There's a bit rough method to do that. If and only if the A set contains some B's element than the call

A.removeAll(B)

will modify the A set. In this situation removeAll will return true (As stated at removeAll docs). But probably you don't want to modify the A set so you may think to act on a copy, like this way:

new HashSet(A).removeAll(B)

and the returning value will be true if the sets are not distinct, that is they have non-empty intersection.

Also see Apache Commons Collections

Upvotes: 4

Zéychin
Zéychin

Reputation: 4205

I would recommend creating a HashMap from set A, and then iterating through set B and checking if any element of B is in A. This would run in O(|A|+|B|) time (as there would be no collisions), whereas retainAll(Collection<?> c) must run in O(|A|*|B|) time.

Upvotes: 3

Suresh Kumar
Suresh Kumar

Reputation: 11767

Use retainAll() in the Set interface. This method provides an intersection of elements common in both sets. See the API docs for more information.

Upvotes: 5

Artem
Artem

Reputation: 4397

You can use retainAll method and get the intersection of your two sets.

Upvotes: 2

Related Questions