package edu.berkeley.nlp.util;
import edu.berkeley.nlp.util.functional.Function;
import edu.berkeley.nlp.util.functional.Predicate;
import java.util.*;
/**
* Created by IntelliJ IDEA.
* User: aria42
* Date: Dec 30, 2008
*/
public class LazyIterable<T,I> implements Iterable<T> {
private Iterable<I> inputIterable;
private Function<I,? extends T> factory;
private int cacheSize;
private Predicate<T> outputPred;
private Set<I> rejectedInputs ;
public LazyIterable(Iterable<I> inputIterable,
Function<I,? extends T> factory,
Predicate<T> outputPred,
int cacheSize)
{
this.inputIterable = inputIterable;
this.factory = factory;
this.cacheSize = cacheSize;
this.outputPred = outputPred;
this.rejectedInputs = new HashSet<I>();
}
private class MyIterator implements Iterator<T> {
private Iterator<I> inputIt;
private Queue<T> cache ;
void ensure() {
// if (cache == null) cache = new ArrayDeque<T>();
if (!cache.isEmpty()) return;
while (cache.size() < cacheSize && inputIt.hasNext()) {
T next = nextInternal();
cache.add(next);
}
}
T nextInternal() {
while (inputIt.hasNext()) {
I input = inputIt.next();
if (rejectedInputs.contains(input)) {
continue;
}
T output = factory.apply(input);
if (outputPred.apply(output)) {
return output;
} else {
rejectedInputs.add(input);
}
}
return null;
}
MyIterator() {
inputIt = inputIterable.iterator();
}
public boolean hasNext() {
return inputIt.hasNext() || !cache.isEmpty();
}
public T next() {
ensure();
return cache.poll() ;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
public Iterator<T> iterator() {
return new MyIterator();
}
public static void main(String[] args) {
List<String> arr = CollectionUtils.makeList("Aria is cool","Isn't he");
Function<String, String[]> factory =
new Function<String,String[]>() {
public String[] apply(String input) {
return input.split("\\s+");
}
};
Iterable<String[]> iterable = new LazyIterable<String[],String>(arr,factory,null,10);
for (String[] strings : iterable) {
System.out.println(Arrays.deepToString(strings));
}
}
}