Skip to content

Instantly share code, notes, and snippets.

@sameei
Last active October 1, 2019 02:59
Show Gist options
  • Save sameei/3e18a35c5cab375a246081a8cebdaf11 to your computer and use it in GitHub Desktop.
Save sameei/3e18a35c5cab375a246081a8cebdaf11 to your computer and use it in GitHub Desktop.
package com.githib.gist.reza_sameei.comparingiterator;
import java.util.*;
public class ComparingIterator<L, R> implements Iterator<ComparingIterator.Pair<L,R>>{
public static interface Comparator<L, R> {
public int compare(L l, R r);
}
public static class StatefulIterator<T> implements Iterator<T> {
private final Iterator<T> underlay;
private T last;
private boolean initialized;
public StatefulIterator(Iterator<T> underlay) {
this.underlay = underlay;
}
@Override
public boolean hasNext() {
return underlay.hasNext();
}
@Override
public T next() {
last = underlay.next();
initialized = true;
return last;
}
public T last() {
if (initialized) return last;
throw new IllegalStateException("StatefulIterator is not initialized yet");
}
public boolean isInitialized() {
return initialized;
}
}
public static class Pair<L,R> {
public final Optional<L> left;
public final Optional<R> right;
public Pair(Optional<L> left, Optional<R> right) {
this.left = left;
this.right = right;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Pair<?, ?> pair = (Pair<?, ?>) o;
if (left != null ? !left.equals(pair.left) : pair.left != null) return false;
return right != null ? right.equals(pair.right) : pair.right == null;
}
@Override
public int hashCode() {
int result = left != null ? left.hashCode() : 0;
result = 31 * result + (right != null ? right.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "Pair{" +
"left=" + left +
", right=" + right +
'}';
}
}
private final Iterator<L> lefts;
private final Iterator<R> rights;
private final Comparator<L, R> comparator;
public ComparingIterator(Iterator<L> lefts, Iterator<R> rights, Comparator<L, R> comparator) {
this.lefts = lefts;
this.rights = rights;
this.comparator = comparator;
}
public static class Iterable<L,R> implements java.lang.Iterable<Pair<L,R>> {
private final java.lang.Iterable<L> lefts;
private final java.lang.Iterable<R> rights;
private final Comparator<L, R> comparator;
public Iterable(java.lang.Iterable<L> lefts, java.lang.Iterable<R> rights, Comparator<L, R> comparator) {
this.lefts = lefts;
this.rights = rights;
this.comparator = comparator;
}
@Override
public Iterator<Pair<L, R>> iterator() {
return new ComparingIterator<>(lefts.iterator(), rights.iterator(), comparator);
}
}
public static <L, R> java.lang.Iterable<Pair<L,R>> fromIterables(
java.lang.Iterable<L> ls,
java.lang.Iterable<R> rs,
Comparator<L,R> c
) {
return new Iterable<L,R>(ls, rs, c);
}
private L left;
private R right;
private boolean initiated = false;
private Pair<L,R> prepareNext() {
if (!initiated) {
initiated = true;
left = lefts.hasNext() ? lefts.next() : null;
right = rights.hasNext() ? rights.next() : null;
}
if (left == null && right == null) return null;
// end of left
if (left == null) {
Pair<L, R> pair = new Pair(Optional.empty(), Optional.of(right));
right = rights.hasNext() ? rights.next() : null;
return pair;
}
// end of right
if (right == null) {
Pair<L, R> pair = new Pair(Optional.of(left), Optional.empty());
left = lefts.hasNext() ? lefts.next() : null;
return pair;
}
int y = comparator.compare(left, right);
if (y == 0) {
Pair<L, R> pair = new Pair(Optional.of(left), Optional.of(right));
left = lefts.hasNext() ? lefts.next() : null;
right = rights.hasNext() ? rights.next() : null;
return pair;
}
if (y < 0) {
Pair<L, R> pair = new Pair(Optional.of(left), Optional.empty());
left = lefts.hasNext() ? lefts.next() : null;
return pair;
}
if (y > 0) {
Pair<L, R> pair = new Pair(Optional.empty(), Optional.of(right));
right = rights.hasNext() ? rights.next() : null;
return pair;
}
return null ; // never
}
private Pair<L, R> last;
@Override
public Pair<L, R> next() {
if (hasNext()) {
Pair<L, R> l = last;
last = null;
return l;
} else throw new IllegalStateException("No Element is Available");
}
@Override
public boolean hasNext() {
if (last != null) return true;
last = prepareNext();
return last != null;
}
public static class StringComparator implements ComparingIterator.Comparator<String, String> {
@Override
public int compare(String left, String right) {
return left.compareTo(right);
}
}
public static <T> Collection<T> listOf(T ... ts) {
ArrayList<T> buffer = new ArrayList<>();
for(T t : ts) {
buffer.add(t);
}
return buffer;
}
public static void main(String[] args) {
System.out.println("=== 1st ===");
ComparingIterator.fromIterables(
listOf("A"),
listOf("B"),
new StringComparator()
).forEach( i -> { System.out.println(i); });
/*
=== 1st ===
Pair{left=Optional[A], right=Optional.empty}
Pair{left=Optional.empty, right=Optional[B]}
*/
System.out.println("=== 2nd ===");
ComparingIterator.fromIterables(
listOf("A", "B"),
listOf("B"),
new StringComparator()
).forEach( i -> { System.out.println(i); });
/*
=== 2nd ===
Pair{left=Optional[A], right=Optional.empty}
Pair{left=Optional[B], right=Optional[B]}
*/
System.out.println("=== 3rd ===");
ComparingIterator.fromIterables(
listOf("A"),
listOf("A", "B"),
new StringComparator()
).forEach( i -> { System.out.println(i); });
/*
=== 3rd ===
Pair{left=Optional[A], right=Optional[A]}
Pair{left=Optional.empty, right=Optional[B]}
*/
System.out.println("=== 4th ===");
ComparingIterator.fromIterables(
listOf("A"),
listOf(),
new StringComparator()
).forEach( i -> { System.out.println(i); });
/*
=== 4th ===
Pair{left=Optional[A], right=Optional.empty}
*/
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment