org.gridkit.jvmtool.event.ExcludeIterator Maven / Gradle / Ivy
package org.gridkit.jvmtool.event;
import java.util.Comparator;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* Subtract one {@link Iterator} from another.
*
* Each of nested {@link Iterator}s MUST produce ordered, duplicate free
* sequence of values.
*
* Result would be ordered, duplicate free sequence of values present
* in iterator A, but not present in V.
*
* @author Alexey Ragozin ([email protected])
*/
public class ExcludeIterator implements Iterator {
@SuppressWarnings("rawtypes")
private static final Comparator NATURAL = new NaturalComaprator();
@SuppressWarnings("unchecked")
public static Iterator exclude(Iterator a, Iterator b) {
return exclude(a, b, NATURAL);
}
public static Iterator exclude(Iterator a, Iterator b, Comparator cmp) {
return new ExcludeIterator(a, b, cmp);
}
@SuppressWarnings("unchecked")
public static Iterable exclude(final Iterable a, final Iterable b) {
return exclude(a, b, NATURAL);
}
public static Iterable exclude(final Iterable a, final Iterable b, final Comparator cmp) {
return new Iterable() {
@Override
public Iterator iterator() {
return exclude(a.iterator(), b.iterator(), cmp);
}
};
}
private final Iterator a;
private final Iterator b;
private final Comparator comparator;
private T peekA;
private T peekB;
@SuppressWarnings("unchecked")
public ExcludeIterator(Iterator a, Iterator b, Comparator cmp) {
this.a = a;
this.b = b;
this.comparator = cmp == null ? NATURAL : cmp;
peekA = a.hasNext() ? next(a) : null;
peekB = b.hasNext() ? next(b) : null;
seek();
}
private T next(Iterator it) {
T v = it.next();
if (v == null) {
throw new NullPointerException("null element is not allowed");
}
return v;
}
private void seek() {
while(peekA != null && peekB != null) {
int c = comparator.compare(peekA, peekB);
if (c > 0) {
peekB = b.hasNext() ? b.next() : null;
continue;
}
else if (c == 0) {
peekA = a.hasNext() ? a.next() : null;
peekB = b.hasNext() ? b.next() : null;
continue;
}
else {
break;
}
}
}
@Override
public boolean hasNext() {
return peekA != null;
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
T result = peekA;
peekA = a.hasNext() ? a.next() : null;
seek();
return result;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
private static class NaturalComaprator implements Comparator> {
@Override
public int compare(Comparable