package oripa.paint.util; import java.util.Iterator; public class PairLoop { /** * loop of (begin, begin+1), ... , (n-2, n-1), (n-1, 0). * @param begin * @param elements Loop target * @param block What to do for the pairs * @return The first element of the last pair, in other word, i of (i, i+1). * null if {@code block} never made a break by returning false. */ public static <Element> Element iterateFrom(Iterator<Element> begin, Iterable<Element> elements, Block<Element> block){ Iterator<Element> iterator = begin; Element e1 = iterator.next(); while(iterator.hasNext()) { Element e2 = iterator.next(); if(block.yield(e1, e2) == false){ return e1; } e1 = e2; } if(block.yield(e1, elements.iterator().next()) == false){ return e1; } return null; } /** * loop of (0, 1), (1, 2) ... (n-2, n-1), (n-1, 0) for n elements. * @param elements Loop target * @param block What to do for the pairs * @return The first element of the last pair, in other word, i of (i, i+1). * null if {@code block} never made a break by returning false. */ public static <Element> Element iterateAll( Iterable<Element> elements, Block<Element> block){ return iterateFrom(elements.iterator(), elements, block); } /** * loop of first {@code count} pairs. * This method does not iterate to (n-1, 0) pair. * @param elements Loop target * @param count the times of iteration * @param block What to do for the pairs * @return The first element of the last pair, in other word, i of (i, i+1). * null if {@code block} never made a break by returning false. */ public static <Element> Element iterateWithCount( Iterable<Element> elements, int count, Block<Element> block){ if(count <= 0){ throw new IllegalArgumentException("count should be larger than 0"); } Iterator<Element> iterator = elements.iterator(); Element e1 = iterator.next(); while(iterator.hasNext() && count > 0) { Element e2 = iterator.next(); if(block.yield(e1, e2) == false){ return e1; } e1 = e2; count--; } return null; } public interface Block<Element>{ /** * this method must return true to go next. * @param element * @param nextElement * @return true if the loop continues, otherwise false. */ public boolean yield(Element element, Element nextElement); } }