package edu.stanford.nlp.util;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.function.Predicate;
/**
* Iterator that suppresses items in another iterator based on a filter function.
*
* @author Dan Klein (klein@cs.stanford.edu)
*/
public class FilteredIterator<T> implements Iterator<T> {
Iterator<T> iterator = null;
Predicate<T> filter = null;
T current = null;
boolean hasCurrent = false;
T currentCandidate() {
return current;
}
void advanceCandidate() {
if (!iterator.hasNext()) {
hasCurrent = false;
current = null;
return;
}
hasCurrent = true;
current = iterator.next();
}
boolean hasCurrentCandidate() {
return hasCurrent;
}
boolean currentCandidateIsAcceptable() {
return filter.test(currentCandidate());
}
void skipUnacceptableCandidates() {
while (hasCurrentCandidate() && !currentCandidateIsAcceptable()) {
advanceCandidate();
}
}
public boolean hasNext() {
return hasCurrentCandidate();
}
public T next() {
T result = currentCandidate();
advanceCandidate();
skipUnacceptableCandidates();
return result;
}
public void remove() {
throw new UnsupportedOperationException();
}
public FilteredIterator(Iterator<T> iterator, Predicate<T> filter) {
this.iterator = iterator;
this.filter = filter;
advanceCandidate();
skipUnacceptableCandidates();
}
public static void main(String[] args) {
Collection<String> c = Arrays.asList(new String[]{"a", "aa", "b", "bb", "cc"});
Iterator<String> i = new FilteredIterator<>(c.iterator(), new Predicate<String>() {
private static final long serialVersionUID = 1L;
public boolean test(String o) {
return o.length() == 1;
}
});
while (i.hasNext()) {
System.out.println("Accepted: " + i.next());
}
}
}