Last active
October 1, 2019 02:59
-
-
Save sameei/3e18a35c5cab375a246081a8cebdaf11 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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