org.gridkit.jvmtool.event.MergeIterator Maven / Gradle / Ivy
package org.gridkit.jvmtool.event;
import java.util.Comparator;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* Merges two {@link Iterator} into one.
*
* 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 either iterator.
*
* @author Alexey Ragozin ([email protected])
*/
public class MergeIterator implements Iterator {
@SuppressWarnings("rawtypes")
private static final Comparator NATURAL = new NaturalComaprator();
@SuppressWarnings("unchecked")
public static Iterator merge(Iterator a, Iterator b) {
return merge(a, b, NATURAL);
}
public static Iterator merge(Iterator a, Iterator b, Comparator cmp) {
return new MergeIterator(a, b, cmp);
}
@SuppressWarnings("unchecked")
public static Iterable merge(final Iterable a, final Iterable b) {
return merge(a, b, NATURAL);
}
public static Iterable merge(final Iterable a, final Iterable b, final Comparator cmp) {
return new Iterable() {
@Override
public Iterator iterator() {
return merge(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 MergeIterator(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;
}
private T next(Iterator it) {
T v = it.next();
if (v == null) {
throw new NullPointerException("null element is not allowed");
}
return v;
}
@Override
public boolean hasNext() {
return peekA != null || peekB != null;
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
T result;
if (peekA == null && peekB != null) {
result = peekB;
peekB = b.hasNext() ? b.next() : null;
}
else if (peekB == null && peekA != null) {
result = peekA;
peekA = a.hasNext() ? a.next() : null;
}
else {
int c = comparator.compare(peekA, peekB);
if (c == 0) {
result = peekA;
peekA = a.hasNext() ? a.next() : null;
peekB = b.hasNext() ? b.next() : null;
}
else if (c > 0) {
result = peekB;
peekB = b.hasNext() ? b.next() : null;
}
else {
result = peekA;
peekA = a.hasNext() ? a.next() : null;
}
}
return result;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
private static class NaturalComaprator implements Comparator> {
@Override
public int compare(Comparable