Skip to content

Commit d9df9ef

Browse files
committed
Add set util for creating a unique visiting iterator among two sets
1 parent 9749cc2 commit d9df9ef

File tree

1 file changed

+60
-0
lines changed
  • src/main/java/software/coley/collections

1 file changed

+60
-0
lines changed

src/main/java/software/coley/collections/Sets.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
import javax.annotation.Nonnull;
44
import javax.annotation.Nullable;
55
import java.util.Arrays;
6+
import java.util.Collections;
67
import java.util.HashSet;
8+
import java.util.Iterator;
79
import java.util.Set;
810

911
/**
@@ -118,4 +120,62 @@ public static <T> Set<T> of(T[] values) {
118120
public static <T> Set<T> ofVar(T... values) {
119121
return of(values);
120122
}
123+
124+
/**
125+
* @param set1
126+
* Some set.
127+
* @param set2
128+
* Some other set.
129+
* @param <T>
130+
* Item type.
131+
*
132+
* @return Iterator over all values among both sets.
133+
*/
134+
@Nonnull
135+
public static <T> Iterator<T> iterator(@Nullable Set<T> set1, @Nullable Set<T> set2) {
136+
if (set1 == null && set2 == null)
137+
return Collections.emptyIterator();
138+
else if (set1 == null)
139+
return set2.iterator();
140+
else if (set2 == null)
141+
return set1.iterator();
142+
return new MergedSetIterator<>(set1, set2);
143+
}
144+
145+
/**
146+
* Set iterator visiting the unique items of two distinct sets.
147+
*
148+
* @param <T>
149+
* Item type.
150+
*/
151+
private static class MergedSetIterator<T> implements Iterator<T> {
152+
private final Iterator<T> leftIt, rightIt;
153+
private final int[] seen;
154+
private int i;
155+
156+
public MergedSetIterator(@Nonnull Set<T> left, @Nonnull Set<T> right) {
157+
leftIt = left.iterator();
158+
rightIt = right.iterator();
159+
seen = new int[left.size() + right.size()];
160+
}
161+
162+
@Override
163+
public boolean hasNext() {
164+
return leftIt.hasNext() || rightIt.hasNext();
165+
}
166+
167+
@Override
168+
public T next() {
169+
T next = leftIt.hasNext() ? leftIt.next() : rightIt.next();
170+
int nextHash = next.hashCode();
171+
int max = i;
172+
i++;
173+
for (int j = 0; j < max; j++) {
174+
if (seen[j] == nextHash)
175+
return next();
176+
}
177+
seen[i] = nextHash;
178+
return next;
179+
}
180+
}
121181
}

0 commit comments

Comments
 (0)