public interface Operator{ public void operate(T item); } public class Functional { /** * Performs a callback on each element-visit, and each element removal */ public static <T> Iterable<T> eventHook(final Iterable<T> iterable, final Operator<T> onVisit, final Operator<T> onRemove) { if (iterable == null) throw new NullPointerException(); if (onVisit == null && onRemove == null) throw new NullPointerException("must specify either onVisit, onRemove or both"); return new Iterable<T>() { @Override public Iterator<T> iterator() { final Iterator<T> iterator = iterable.iterator(); return new Iterator<T>() { @Override public boolean hasNext() { return iterator.hasNext(); } @Override public T next() { this.current = iterator.next(); if (onVisit != null) onVisit.operate(this.current); return this.current; } @Override public void remove() { iterator.remove(); if (onRemove != null) onRemove.operate(this.current); } // private T current; }; } }; } }
Example:
Operator<String> onVisit= new Operator<String>()
{
public void operate(String text)
{
System.out.println("visited: "+text);
}
};
Operator<String> onRemove= new Operator<String>()
{
public void operate(String text)
{
System.out.println("removed: "+text);
}
};
Iterable<String> data = ...;
for(String item: eventHook(data, onVisit, onRemove))
{
if(item.length() > String.valueOf(Math.PI))
System.out.println("this text is longer than PI!");
}
Once you created an Iterable (say, a filtered view on a List) you can iterate over it as often as you want. No need to create a new Iterable.
With the support for closures in Java 7 a lot of the boilerplate code will disappear.
The example is the one from the Transform post.
ReplyDeleteYeah... thanks. Fixed it!
ReplyDelete