What is the simplest way to make a union or an intersection of Set
s in Java? I've seen some strange solutions to this simple problem (e.g. manually iterating the two sets).

- 18,032
- 13
- 118
- 133
-
1Why do you think that manually iterating the sets is a "strange" solution? – Michael Jun 30 '18 at 08:42
-
11@Michael Because in my opinion when there is a built-in API of java, using that: 1. Reduces my work (lines of code) and improves readability 2. Standardizes the code (other developers understand it with a glimpse) 3. I do not have to maintain it 4. It is automatically updated, improved, optimized,... by java developers – Mahozad Jun 30 '18 at 09:17
5 Answers
The simplest one-line solution is this:
set1.addAll(set2); // Union
set1.retainAll(set2); // Intersection
The above solution is destructive, meaning that contents of the original set1 my change.
If you don't want to touch your existing sets, create a new set:
var result = new HashSet<>(set1); // In Java 10 and above
Set<Integer> result = new HashSet<>(set1); // In Java < 10
result.addAll(set2); // Union
result.retainAll(set2); // Intersection

- 18,032
- 13
- 118
- 133
-
instead of using Set
result = new HashSet<>(set1); HashSet support clone operation that will far more efficient – Arnault Le Prévost-Corvellec Jun 30 '18 at 08:37 -
7@ArnaultLePrévost-Corvellec reference? Usage of `clone()` is heavily frowned upon and recommended to get avoided in all cases. See [Effective Java 11](https://medium.com/@biratkirat/learning-effective-java-item-11-390fbf94e41c) (Original book, [full PDF](http://wavelino.coffeecup.com/pdf/EffectiveJava.pdf)) (Item 13 in the 3rd edition) – Boris the Spider Jun 30 '18 at 10:41
-
2your are speaking about cloneable interface that could be very tricky to implement and most of the time the contract of clone is not respect by developers. I ll not demonstrate that HashSet.clone() method respect the contract of clone ... please read the code of this methods if you see the difference .here the purpuse is to make a shallow copy that clone made far fastest as the constructor that is code for any collection... hashset add method is quite heavy thats why for perfomance issue clone will be the best way ... – Arnault Le Prévost-Corvellec Jun 30 '18 at 12:47
-
I think if we don't have the constraint about the number of new created sets, this is a good solution – Minh Trần Jun 30 '18 at 17:40
While guava for sure is neater and pretty much standard, here's a non destructive way to do union and intersect using only standard Java
Set s1 = Set.of(1,2,3);
Set s2 = Set.of(3,4,5);
Set union = Stream.concat(s1.stream(),s2.stream()).collect(Collectors.toSet());
Set intersect = s1.stream().filter(s2::contains).collect(Collectors.toSet());

- 2,010
- 16
- 29

- 1,799
- 16
- 19
-
1Worth noting that with this code, there's no need for `s1` to be a set. Any stream would work without performance degradation (since it's `s2` that's being checked, that's where the set-ness comes into play) – Alexander Jul 19 '19 at 03:04
-
1This is only possible since Java 8 (and Java 9 for `Set.of(...)` set initialization) – fbastien Mar 06 '20 at 18:06
You can achieve this using Google's Guava library
. The following explanation is given below with the help of an example:
// Set a
Set<String> a = new HashSet<String>();
a.add("x");
a.add("y");
a.add("z");
// Set b
Set<String> b = new HashSet<String>();
b.add("x");
b.add("p");
b.add("q");
Now, Calculating Intersection of two Set in Java:
Set<String> intersection = Sets.intersection(a, b);
System.out.printf("Intersection of two Set %s and %s in Java is %s %n",
a.toString(), b.toString(), intersection.toString());
Output: Intersection of two Set [z, y, x] and [q, p, x] in Java is [x]
Similarly, Calculating Union of two Set in Java:
Set<String> union = Sets.union(a, b);
System.out.printf("Union of two Set %s and %s in Java is %s %n",
a.toString(), b.toString(), union.toString());
Output: Union of two Set [z, y, x] and [q, p, x] in Java is [q, p, x, z, y]
You can read more about guava library at https://google.github.io/guava/releases/18.0/api/docs/
In order to add guava library to your project, You can see https://stackoverflow.com/a/4648947/8258942

- 5,053
- 4
- 14
- 26
-
2While the library method is nice, I don't see any reason to add a heavyweight library and all the overhead just for set-intersection/union when Java already offers it. Of course, if you already have it in your project you can just use it. – Zabuzard Jun 30 '18 at 10:26
-
4@Zabuza it provides an intersection/union _view_ - which is very different to the JDK options. If you don't need that, of course, then the library is unneccessary. – Boris the Spider Jun 30 '18 at 11:23
-
@Zabuzard The Guava library also offers other set-manipulation methods (difference, complementOf, cartesianProduct, intersection, powerSet, subSet, et al.), so I think it's a great addition to one's toolbox. – Aquarelle Nov 09 '22 at 20:51
import java.util.*;
public class sets {
public static void swap(int array[], int a, int b) { // Swap function for sorting
int temp = array[a];
array[a] = array[b];
array[b] = temp;
}
public static int[] sort(int array[]) { // sort function for binary search (Selection sort)
int minIndex;
int j;
for (int i = 0; i < array.length; i++) {
minIndex = i;
for (j = i + 1; j < array.length; j++) {
if (array[minIndex] > array[j])
minIndex = j;
}
swap(array, minIndex, i);
}
return array;
}
public static boolean search(int array[], int search) { // Binary search for intersection and difference
int l = array.length;
int mid = 0;
int lowerLimit = 0, upperLimit = l - 1;
while (lowerLimit <= upperLimit) {
mid = (lowerLimit + upperLimit) / 2;
if (array[mid] == search) {
return true;
} else if (array[mid] > search)
upperLimit = mid - 1;
else if (array[mid] < search)
lowerLimit = mid + 1;
}
return false;
}
public static int[] append(int array[], int add) { // To add elements
int newArray[] = new int[array.length + 1];
for (int i = 0; i < array.length; i++) {
newArray[i] = array[i];
}
newArray[array.length] = add;
newArray = sort(newArray);
return newArray;
}
public static int[] remove(int array[], int index) { // To remove duplicates
int anotherArray[] = new int[array.length - 1];
int k = 0;
if (array == null || index < 0 || index > array.length) {
return array;
}
for (int i = 0; i < array.length; i++) {
if (index == i) {
continue;
}
anotherArray[k++] = array[i];
}
return anotherArray;
}
public static void Union(int A[], int B[]) { // Union of a set
int union[] = new int[A.length + B.length];
for (int i = 0; i < A.length; i++) {
union[i] = A[i];
}
for (int j = A.length, i = 0; i < B.length || j < union.length; i++, j++) {
union[j] = B[i];
}
for (int i = 0; i < union.length; i++) {
for (int j = 0; j < union.length; j++) {
if (union[i] == union[j] && j != i) {
union = remove(union, j); // Removing duplicates
}
}
}
union = sort(union);
System.out.print("A U B = {"); // Printing
for (int i = 0; i < union.length; i++) {
if (i != union.length - 1)
System.out.print(union[i] + ", ");
else
System.out.print(union[i] + "}");
}
}
public static void Intersection(int A[], int B[]) {
int greater = (A.length > B.length) ? (A.length) : (B.length);
int intersect[] = new int[1];
int G[] = (A.length > B.length) ? A : B;
int L[] = (A.length < B.length) ? A : B;
for (int i = 0; i < greater; i++) {
if (search(L, G[i]) == true) { // Common elements
intersect = append(intersect, G[i]);
}
}
for (int i = 0; i < intersect.length; i++) {
for (int j = 0; j < intersect.length; j++) {
if (intersect[i] == intersect[j] && j != i) {
intersect = remove(intersect, j); // Removing duplicates
}
}
}
System.out.print("A ∩ B = {"); // Printing
for (int i = 1; i < intersect.length; i++) {
if (i != intersect.length - 1)
System.out.print(intersect[i] + ", ");
else
System.out.print(intersect[i] + "}");
}
}
public static void difference(int A[], int B[]) {
int diff[] = new int[1];
int G[] = (A.length > B.length) ? A : B;
int L[] = (A.length < B.length) ? A : B;
int greater = G.length;
for (int i = 0; i < greater; i++) {
if (search(L, G[i]) == false) {
diff = append(diff, G[i]); // Elements not in common
}
}
for (int i = 0; i < diff.length; i++) {
for (int j = 0; j < diff.length; j++) {
if (diff[i] == diff[j] && j != i) {
diff = remove(diff, j); // Removing duplicates
}
}
}
System.out.println("Where A is the larger set, and B is the smaller set.");
System.out.print("A - B = {"); // Printing
for (int i = 1; i < diff.length; i++) {
if (i != diff.length - 1)
System.out.print(diff[i] + ", ");
else
System.out.print(diff[i] + "}");
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the operation");
String operation = sc.next().toLowerCase();
System.out.println("Enter the length of the first set.");
int l1 = sc.nextInt();
System.out.println("Enter the length of the second set.");
int l2 = sc.nextInt();
int A[] = new int[l1];
int B[] = new int[l2];
System.out.println("Enter the elements of the first set.");
System.out.print("A = ");
for (int i = 0; i < l1; i++) {
A[i] = sc.nextInt();
}
System.out.println("Enter the elements of the second set.");
System.out.print("B = ");
for (int i = 0; i < l2; i++) {
B[i] = sc.nextInt();
}
A = sort(A); // Sorting the sets before passing
B = sort(B);
sc.close();
switch (operation) {
case "union":
Union(A, B);
break;
case "intersection":
Intersection(A, B);
break;
case "difference":
difference(B, A);
break;
default:
System.out.println("Invalid Operation");
}
}
}

- 11
- 2
-
1Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community May 15 '22 at 05:34
When I think of union and intersection, it is in the first loop an operation on sets, i.e. a map
Set<T> x Set<T> → Set<T>
Not clear, why it would appear in Java design that shirtsleeved.
static <T> Set<T> union(Set<T> a, Set<T> b)
{
Set<T> res = new HashSet<T>(a);
res.addAll(b);
return res;
}
static <T> Set<T> intersection(Set<T> a, Set<T> b)
{
Set<T> res = new HashSet<T>(a);
res.retainAll(b);
return res;
}

- 661
- 6
- 7