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)); } } }