Author: mbenson Date: Wed Nov 13 17:54:37 2013 New Revision: 1541636 URL: http://svn.apache.org/r1541636 Log: remove bounds from Range<S>; Range-=Iterable; implement #isEmpty() in AbstractRange()
Modified: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/IteratorToGeneratorAdapter.java commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/AbstractRange.java commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/CharacterRange.java commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/DoubleRange.java commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/FloatRange.java commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/IntegerRange.java commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/LongRange.java commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/NumericRange.java commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/Range.java commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/example/kata/two/TestBinaryChop.java commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/loop/TestIteratorToGeneratorAdapter.java commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/range/TestLongRange.java Modified: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/IteratorToGeneratorAdapter.java URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/IteratorToGeneratorAdapter.java?rev=1541636&r1=1541635&r2=1541636&view=diff ============================================================================== --- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/IteratorToGeneratorAdapter.java (original) +++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/IteratorToGeneratorAdapter.java Wed Nov 13 17:54:37 2013 @@ -27,6 +27,47 @@ import org.apache.commons.lang3.Validate * @version $Revision: 1508677 $ $Date: 2013-07-30 19:48:02 -0300 (Tue, 30 Jul 2013) $ */ public final class IteratorToGeneratorAdapter<E> extends LoopGenerator<E> { + private static class EqualityIterator<E> implements Iterator<E> { + final Iterable<? extends E> owner; + final Iterator<? extends E> wrapped; + + EqualityIterator(Iterable<? extends E> owner) { + super(); + this.owner = Validate.notNull(owner); + this.wrapped = owner.iterator(); + } + + public boolean hasNext() { + return wrapped.hasNext(); + } + + public E next() { + return wrapped.next(); + } + + public void remove() { + wrapped.remove(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof EqualityIterator<?> == false) { + return false; + } + return ((EqualityIterator<?>) obj).owner.equals(owner); + } + + @Override + public int hashCode() { + int result = 71 << 4; + result |= owner.hashCode(); + return result; + } + } + // instance variables //----------------------------------------------------- @@ -106,4 +147,14 @@ public final class IteratorToGeneratorAd return null == iter ? null : new IteratorToGeneratorAdapter<E>(iter); } + /** + * Adapt an Iterable to the Generator interface. + * + * @param <E> the type of elements held in this generator. + * @param iterable to adapt + * @return IteratorToGeneratorAdapter + */ + public static <E> IteratorToGeneratorAdapter<E> adapt(Iterable<? extends E> iterable) { + return null == iterable ? null : new IteratorToGeneratorAdapter<E>(new EqualityIterator<E>(iterable)); + } } Modified: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/AbstractRange.java URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/AbstractRange.java?rev=1541636&r1=1541635&r2=1541636&view=diff ============================================================================== --- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/AbstractRange.java (original) +++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/AbstractRange.java Wed Nov 13 17:54:37 2013 @@ -17,17 +17,21 @@ package org.apache.commons.functor.range; import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import org.apache.commons.functor.BinaryFunction; +import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.builder.EqualsBuilder; /** * Abstract {@link Range}. * - * @param <T> - * @param <S> + * @param <T> type of element + * @param <S> type of step */ -public abstract class AbstractRange<T extends Comparable<?>, S extends Comparable<?>> implements Range<T, S> { +public abstract class AbstractRange<T extends Comparable<T>, S> implements Range<T, S> { /** * Left limit. @@ -44,18 +48,22 @@ public abstract class AbstractRange<T ex */ protected final S step; + private final BinaryFunction<T, S, T> nextValue; + /** * Create a new {@link AbstractRange}. * * @param leftEndpoint left endpoint * @param rightEndpoint right endpoint * @param step increment step + * @param nextValue function to implement the taking of a step */ - protected AbstractRange(Endpoint<T> leftEndpoint, Endpoint<T> rightEndpoint, S step) { + protected AbstractRange(Endpoint<T> leftEndpoint, Endpoint<T> rightEndpoint, S step, BinaryFunction<T, S, T> nextValue) { super(); this.leftEndpoint = Validate.notNull(leftEndpoint, "Left Endpoint argument must not be null"); this.rightEndpoint = Validate.notNull(rightEndpoint, "Right Endpoint argument must not be null"); this.step = Validate.notNull(step, "step must not be null"); + this.nextValue = Validate.notNull(nextValue, "next value function"); } /** @@ -82,11 +90,11 @@ public abstract class AbstractRange<T ex /** * {@inheritDoc} */ - public boolean containsAll(Collection<T> col) { - if (col == null || col.isEmpty()) { + public boolean containsAll(Collection<T> coll) { + if (coll == null || coll.isEmpty()) { return false; } - for (T t : col) { + for (T t : coll) { if (!contains(t)) { return false; } @@ -94,15 +102,30 @@ public abstract class AbstractRange<T ex return true; } - // iterable, iterator methods + // iterable // --------------------------------------------------------------- /** * {@inheritDoc} */ - public void remove() { - throw new UnsupportedOperationException(); + public final Iterator<T> iterator() { + // empty range -> empty iterator: + if (isEmpty()) { + return Collections.<T> emptySet().iterator(); + } + // not empty and same values -> single-value range: + if (ObjectUtils.equals(leftEndpoint.getValue(), rightEndpoint.getValue())) { + return Collections.singleton(leftEndpoint.getValue()).iterator(); + } + return createIterator(); } + /** + * Create a non-empty iterator. + * + * @return Iterator + */ + protected abstract Iterator<T> createIterator(); + // object methods // --------------------------------------------------------------- /** @@ -145,4 +168,32 @@ public abstract class AbstractRange<T ex hash ^= this.step.hashCode(); return hash; } + + /** + * {@inheritDoc} + */ + public final boolean isEmpty() { + final T leftValue = leftEndpoint.getValue(); + final T rightValue = rightEndpoint.getValue(); + + final int cmp = ObjectUtils.compare(leftValue, rightValue); + final boolean closedLeft = leftEndpoint.getBoundType() == BoundType.CLOSED; + final boolean closedRight = rightEndpoint.getBoundType() == BoundType.CLOSED; + + if (cmp == 0 && !(closedLeft && closedRight)) { + return true; + } + + final T firstValue = closedLeft ? leftValue : nextValue.evaluate(leftValue, step); + + final int cmpFirst = ObjectUtils.compare(firstValue, rightValue); + + if (cmpFirst == 0) { + return !closedRight; + } + + final boolean ascending = cmp < 0; + return ascending ? cmpFirst > 0 : cmpFirst < 0; + } + } Modified: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/CharacterRange.java URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/CharacterRange.java?rev=1541636&r1=1541635&r2=1541636&view=diff ============================================================================== --- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/CharacterRange.java (original) +++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/CharacterRange.java Wed Nov 13 17:54:37 2013 @@ -29,33 +29,16 @@ import org.apache.commons.lang3.Validate */ public final class CharacterRange extends AbstractRange<Character, Integer> { - // attributes - // --------------------------------------------------------------- - /** - * Default left bound type. - */ - public static final BoundType DEFAULT_LEFT_BOUND_TYPE = BoundType.CLOSED; - - /** - * Default right bound type. - */ - public static final BoundType DEFAULT_RIGHT_BOUND_TYPE = BoundType.CLOSED; - - /** - * Current value. - */ - private char currentValue; - /** * Calculate default step. */ - public static final BinaryFunction<Character, Character, Integer> DEFAULT_STEP - = new BinaryFunction<Character, Character, Integer>() { + public static final BinaryFunction<Character, Character, Integer> DEFAULT_STEP = + new BinaryFunction<Character, Character, Integer>() { - public Integer evaluate(Character left, Character right) { - return left > right ? -1 : 1; - } - }; + public Integer evaluate(Character left, Character right) { + return left > right ? -1 : 1; + } + }; // constructors // --------------------------------------------------------------- @@ -100,18 +83,17 @@ public final class CharacterRange extend * @throws NullPointerException if either {@link Endpoint} is {@code null} */ public CharacterRange(Endpoint<Character> from, Endpoint<Character> to, int step) { - super(from, to, Integer.valueOf(step)); + super(from, to, Integer.valueOf(step), new BinaryFunction<Character, Integer, Character>() { + + public Character evaluate(Character left, Integer right) { + return Character.valueOf((char) (left.charValue() + right.intValue())); + } + }); final char f = from.getValue(); final char t = to.getValue(); Validate.isTrue(f == t || Integer.signum(step) == Integer.signum(t - f), "Will never reach '%s' from '%s' using step %s", t, f, step); - - if (from.getBoundType() == BoundType.CLOSED) { - this.currentValue = f; - } else { - this.currentValue = (char) (f + step); - } } /** @@ -144,69 +126,6 @@ public final class CharacterRange extend // range methods // --------------------------------------------------------------- - // iterable, iterator methods - // --------------------------------------------------------------- - /** - * {@inheritDoc} - */ - public boolean hasNext() { - final int to = this.rightEndpoint.getValue(); - if (step < 0) { - if (this.rightEndpoint.getBoundType() == BoundType.CLOSED) { - return this.currentValue >= to; - } else { - return this.currentValue > to; - } - } else { - if (this.rightEndpoint.getBoundType() == BoundType.CLOSED) { - return this.currentValue <= to; - } else { - return this.currentValue < to; - } - } - } - - /** - * {@inheritDoc} - */ - public Character next() { - final int step = this.getStep(); - final char r = this.currentValue; - this.currentValue += step; - return Character.valueOf(r); - } - - /** - * {@inheritDoc} - */ - public Iterator<Character> iterator() { - return this; - } - - /** - * {@inheritDoc} - */ - public boolean isEmpty() { - double leftValue = this.getLeftEndpoint().getValue().charValue(); - double rightValue = this.getRightEndpoint().getValue().charValue(); - boolean closedLeft = this.getLeftEndpoint().getBoundType() == BoundType.CLOSED; - boolean closedRight = this.getRightEndpoint().getBoundType() == BoundType.CLOSED; - if (!closedLeft && !closedRight - && this.getLeftEndpoint().equals(this.getRightEndpoint())) { - return Boolean.TRUE; - } - double step = this.getStep().intValue(); - if (step > 0.0) { - double firstValue = closedLeft ? leftValue : leftValue + step; - return closedRight ? firstValue > rightValue - : firstValue >= rightValue; - } else { - double firstValue = closedLeft ? leftValue : leftValue + step; - return closedRight ? firstValue < rightValue - : firstValue <= rightValue; - } - } - /** * {@inheritDoc} */ @@ -240,4 +159,44 @@ public final class CharacterRange extend return ((double) (value - firstValue) / step + 1) % 1.0 == 0.0; } + /** + * {@inheritDoc} + */ + protected Iterator<Character> createIterator() { + return new Iterator<Character>() { + private char currentValue; + + { + currentValue = leftEndpoint.getValue(); + + if (leftEndpoint.getBoundType() == BoundType.OPEN) { + this.currentValue += step; + } + } + + public void remove() { + throw new UnsupportedOperationException(); + } + + public Character next() { + final int step = getStep(); + final char r = currentValue; + currentValue += step; + return Character.valueOf(r); + } + + public boolean hasNext() { + final int cmp = Integer.compare(currentValue, rightEndpoint.getValue()); + + if (cmp == 0) { + return rightEndpoint.getBoundType() == BoundType.CLOSED; + } + if (step > 0) { + return cmp < 0; + } + return cmp > 0; + } + }; + } + } Modified: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/DoubleRange.java URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/DoubleRange.java?rev=1541636&r1=1541635&r2=1541636&view=diff ============================================================================== --- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/DoubleRange.java (original) +++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/DoubleRange.java Wed Nov 13 17:54:37 2013 @@ -29,14 +29,6 @@ import org.apache.commons.lang3.Validate */ public class DoubleRange extends NumericRange<Double> { - // attributes - // --------------------------------------------------------------- - - /** - * Current value. - */ - private double currentValue; - /** * Calculate default step. */ @@ -126,18 +118,18 @@ public class DoubleRange extends Numeric * @throws NullPointerException if either {@link Endpoint} is {@code null} */ public DoubleRange(Endpoint<Double> from, Endpoint<Double> to, double step) { - super(from, to, Double.valueOf(step)); + super(from, to, Double.valueOf(step), new BinaryFunction<Double, Double, Double>() { + + public Double evaluate(Double left, Double right) { + return Double.valueOf(left.doubleValue() + right.doubleValue()); + } + }); + final double f = from.getValue(); final double t = to.getValue(); Validate.isTrue(f == t || Math.signum(step) == Math.signum(t - f), "Will never reach '%s' from '%s' using step %s", t, f, step); - - if (from.getBoundType() == BoundType.CLOSED) { - this.currentValue = f; - } else { - this.currentValue = f + step; - } } /** @@ -155,43 +147,44 @@ public class DoubleRange extends Numeric this(new Endpoint<Double>(from, leftBoundType), new Endpoint<Double>(to, rightBoundType), step); } - // iterable, iterator methods - // --------------------------------------------------------------- /** * {@inheritDoc} */ - public boolean hasNext() { - final double to = this.rightEndpoint.getValue(); - if (step < 0) { - if (this.rightEndpoint.getBoundType() == BoundType.CLOSED) { - return this.currentValue >= to; - } else { - return this.currentValue > to; + protected Iterator<Double> createIterator() { + return new Iterator<Double>() { + private double currentValue; + + { + currentValue = leftEndpoint.getValue(); + + if (leftEndpoint.getBoundType() == BoundType.OPEN) { + this.currentValue += step; + } + } + + public void remove() { + throw new UnsupportedOperationException(); } - } else { - if (this.rightEndpoint.getBoundType() == BoundType.CLOSED) { - return this.currentValue <= to; - } else { - return this.currentValue < to; + + public Double next() { + final double step = getStep(); + final double r = currentValue; + currentValue += step; + return Double.valueOf(r); } - } - } - /** - * {@inheritDoc} - */ - public Double next() { - final double step = this.getStep(); - final double r = this.currentValue; - this.currentValue += step; - return Double.valueOf(r); - } + public boolean hasNext() { + final int cmp = Double.compare(currentValue, rightEndpoint.getValue()); - /** - * {@inheritDoc} - */ - public Iterator<Double> iterator() { - return this; + if (cmp == 0) { + return rightEndpoint.getBoundType() == BoundType.CLOSED; + } + if (step > 0d) { + return cmp < 0; + } + return cmp > 0; + } + }; } } Modified: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/FloatRange.java URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/FloatRange.java?rev=1541636&r1=1541635&r2=1541636&view=diff ============================================================================== --- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/FloatRange.java (original) +++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/FloatRange.java Wed Nov 13 17:54:37 2013 @@ -33,11 +33,6 @@ public class FloatRange extends NumericR // --------------------------------------------------------------- /** - * Current value. - */ - private float currentValue; - - /** * Calculate default step. */ public static final BinaryFunction<Float, Float, Float> DEFAULT_STEP = new BinaryFunction<Float, Float, Float>() { @@ -111,18 +106,17 @@ public class FloatRange extends NumericR * @throws NullPointerException if either {@link Endpoint} is {@code null} */ public FloatRange(Endpoint<Float> from, Endpoint<Float> to, float step) { - super(from, to, Float.valueOf(step)); + super(from, to, Float.valueOf(step), new BinaryFunction<Float, Float, Float>() { + + public Float evaluate(Float left, Float right) { + return Float.valueOf(left.floatValue() + right.floatValue()); + } + }); final float f = from.getValue(); final float t = to.getValue(); Validate.isTrue(f == t || Math.signum(step) == Math.signum(t - f), "Will never reach '%s' from '%s' using step %s", t, f, step); - - if (from.getBoundType() == BoundType.CLOSED) { - this.currentValue = f; - } else { - this.currentValue = f + step; - } } /** @@ -154,43 +148,44 @@ public class FloatRange extends NumericR this(new Endpoint<Float>(from, leftBoundType), new Endpoint<Float>(to, rightBoundType), step); } - // iterable, iterator methods - // --------------------------------------------------------------- /** * {@inheritDoc} */ - public boolean hasNext() { - final float to = this.rightEndpoint.getValue(); - if (step < 0) { - if (this.rightEndpoint.getBoundType() == BoundType.CLOSED) { - return this.currentValue >= to; - } else { - return this.currentValue > to; + protected Iterator<Float> createIterator() { + return new Iterator<Float>() { + private float currentValue; + + { + currentValue = leftEndpoint.getValue(); + + if (leftEndpoint.getBoundType() == BoundType.OPEN) { + this.currentValue += step; + } } - } else { - if (this.rightEndpoint.getBoundType() == BoundType.CLOSED) { - return this.currentValue <= to; - } else { - return this.currentValue < to; + + public void remove() { + throw new UnsupportedOperationException(); } - } - } - /** - * {@inheritDoc} - */ - public Float next() { - final float step = this.getStep(); - final float r = this.currentValue; - this.currentValue += step; - return Float.valueOf(r); - } + public Float next() { + final float step = getStep(); + final float r = currentValue; + currentValue += step; + return Float.valueOf(r); + } - /** - * {@inheritDoc} - */ - public Iterator<Float> iterator() { - return this; + public boolean hasNext() { + final int cmp = Float.compare(currentValue, rightEndpoint.getValue()); + + if (cmp == 0) { + return rightEndpoint.getBoundType() == BoundType.CLOSED; + } + if (step > 0f) { + return cmp < 0; + } + return cmp > 0; + } + }; } } Modified: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/IntegerRange.java URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/IntegerRange.java?rev=1541636&r1=1541635&r2=1541636&view=diff ============================================================================== --- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/IntegerRange.java (original) +++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/IntegerRange.java Wed Nov 13 17:54:37 2013 @@ -23,7 +23,7 @@ import org.apache.commons.lang3.Validate /** * A range of integers. - * + * * @since 1.0 * @version $Revision: 1385335 $ $Date: 2012-09-16 15:08:31 -0300 (Sun, 16 Sep 2012) $ */ @@ -33,28 +33,25 @@ public class IntegerRange extends Numeri // --------------------------------------------------------------- /** - * Current value. - */ - private int currentValue; - - /** * Calculate default step. */ public static final BinaryFunction<Integer, Integer, Integer> DEFAULT_STEP = - new BinaryFunction<Integer, Integer, Integer>() { + new BinaryFunction<Integer, Integer, Integer>() { - public Integer evaluate(Integer left, Integer right) { - return left > right ? -1 : 1; - } - }; + public Integer evaluate(Integer left, Integer right) { + return left > right ? -1 : 1; + } + }; // constructors // --------------------------------------------------------------- /** * Create a new IntegerRange. - * - * @param from start - * @param to end + * + * @param from + * start + * @param to + * end */ public IntegerRange(Number from, Number to) { this(from.intValue(), to.intValue()); @@ -62,10 +59,13 @@ public class IntegerRange extends Numeri /** * Create a new IntegerRange. - * - * @param from start - * @param to end - * @param step increment + * + * @param from + * start + * @param to + * end + * @param step + * increment */ public IntegerRange(Number from, Number to, Number step) { this(from.intValue(), to.intValue(), step.intValue()); @@ -73,9 +73,11 @@ public class IntegerRange extends Numeri /** * Create a new IntegerRange. - * - * @param from start - * @param to end + * + * @param from + * start + * @param to + * end */ public IntegerRange(int from, int to) { this(from, to, DEFAULT_STEP.evaluate(from, to).intValue()); @@ -83,10 +85,13 @@ public class IntegerRange extends Numeri /** * Create a new IntegerRange. - * - * @param from start - * @param to end - * @param step increment + * + * @param from + * start + * @param to + * end + * @param step + * increment */ public IntegerRange(int from, int to, int step) { this(from, DEFAULT_LEFT_BOUND_TYPE, to, DEFAULT_RIGHT_BOUND_TYPE, step); @@ -94,10 +99,13 @@ public class IntegerRange extends Numeri /** * Create a new IntegerRange. - * - * @param from start - * @param to end - * @throws NullPointerException if either {@link Endpoint} is {@code null} + * + * @param from + * start + * @param to + * end + * @throws NullPointerException + * if either {@link Endpoint} is {@code null} */ public IntegerRange(Endpoint<Integer> from, Endpoint<Integer> to) { this(from, to, DEFAULT_STEP.evaluate(from.getValue(), to.getValue())); @@ -105,92 +113,107 @@ public class IntegerRange extends Numeri /** * Create a new IntegerRange. - * - * @param from start - * @param to end - * @param step increment - * @throws NullPointerException if either {@link Endpoint} is {@code null} + * + * @param from + * start + * @param leftBoundType + * type of left bound + * @param to + * end + * @param rightBoundType + * type of right bound + * @throws NullPointerException + * if either {@link BoundType} is {@code null} + */ + public IntegerRange(int from, BoundType leftBoundType, int to, BoundType rightBoundType) { + this(from, leftBoundType, to, rightBoundType, DEFAULT_STEP.evaluate(from, to)); + } + + /** + * Create a new IntegerRange. + * + * @param from + * start + * @param to + * end + * @param step + * increment + * @throws NullPointerException + * if either {@link Endpoint} is {@code null} */ public IntegerRange(Endpoint<Integer> from, Endpoint<Integer> to, int step) { - super(from, to, Integer.valueOf(step)); + super(from, to, Integer.valueOf(step), new BinaryFunction<Integer, Integer, Integer>() { + + public Integer evaluate(Integer left, Integer right) { + return Integer.valueOf(left.intValue() + right.intValue()); + } + }); + final int f = from.getValue(); final int t = to.getValue(); Validate.isTrue(f == t || Integer.signum(step) == Integer.signum(t - f), "Will never reach '%s' from '%s' using step %s", t, f, step); - - if (from.getBoundType() == BoundType.CLOSED) { - this.currentValue = f; - } else { - this.currentValue = f + step; - } } /** * Create a new IntegerRange. - * - * @param from start - * @param leftBoundType type of left bound - * @param to end - * @param rightBoundType type of right bound - * @throws NullPointerException if either {@link BoundType} is {@code null} - */ - public IntegerRange(int from, BoundType leftBoundType, int to, - BoundType rightBoundType) { - this(from, leftBoundType, to, rightBoundType, DEFAULT_STEP.evaluate(from, to)); - } - - /** - * Create a new IntegerRange. - * - * @param from start - * @param leftBoundType type of left bound - * @param to end - * @param rightBoundType type of right bound - * @param step increment - * @throws NullPointerException if either {@link BoundType} is {@code null} + * + * @param from + * start + * @param leftBoundType + * type of left bound + * @param to + * end + * @param rightBoundType + * type of right bound + * @param step + * increment + * @throws NullPointerException + * if either {@link BoundType} is {@code null} */ public IntegerRange(int from, BoundType leftBoundType, int to, BoundType rightBoundType, int step) { this(new Endpoint<Integer>(from, leftBoundType), new Endpoint<Integer>(to, rightBoundType), step); } - // iterable, iterator methods - // --------------------------------------------------------------- /** * {@inheritDoc} */ - public boolean hasNext() { - final int to = this.rightEndpoint.getValue(); - if (step < 0) { - if (this.rightEndpoint.getBoundType() == BoundType.CLOSED) { - return this.currentValue >= to; - } else { - return this.currentValue > to; - } - } else { - if (this.rightEndpoint.getBoundType() == BoundType.CLOSED) { - return this.currentValue <= to; - } else { - return this.currentValue < to; + protected Iterator<Integer> createIterator() { + return new Iterator<Integer>() { + private int currentValue; + + { + currentValue = leftEndpoint.getValue(); + + if (leftEndpoint.getBoundType() == BoundType.OPEN) { + this.currentValue += step; + } } - } - } - /** - * {@inheritDoc} - */ - public Integer next() { - final int step = this.getStep(); - final int r = this.currentValue; - this.currentValue += step; - return Integer.valueOf(r); - } + public void remove() { + throw new UnsupportedOperationException(); + } - /** - * {@inheritDoc} - */ - public Iterator<Integer> iterator() { - return this; + public Integer next() { + final int step = getStep(); + final int r = currentValue; + currentValue += step; + return Integer.valueOf(r); + } + + public boolean hasNext() { + final int cmp = Integer.compare(currentValue, rightEndpoint.getValue()); + + if (cmp == 0) { + return rightEndpoint.getBoundType() == BoundType.CLOSED; + } + if (step > 0) { + return cmp < 0; + } + return cmp > 0; + } + }; } } Modified: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/LongRange.java URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/LongRange.java?rev=1541636&r1=1541635&r2=1541636&view=diff ============================================================================== --- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/LongRange.java (original) +++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/LongRange.java Wed Nov 13 17:54:37 2013 @@ -32,11 +32,6 @@ public final class LongRange extends Num //--------------------------------------------------------------- /** - * Current value. - */ - private long currentValue; - - /** * Calculate default step. */ public static final BinaryFunction<Long, Long, Long> DEFAULT_STEP = new BinaryFunction<Long, Long, Long>() { @@ -135,18 +130,18 @@ public final class LongRange extends Num * @throws NullPointerException if either {@link Endpoint} is {@code null} */ public LongRange(Endpoint<Long> from, Endpoint<Long> to, long step) { - super(from, to, Long.valueOf(step)); + super(from, to, Long.valueOf(step), new BinaryFunction<Long, Long, Long>() { + + public Long evaluate(Long left, Long right) { + return Long.valueOf(left.longValue() + right.longValue()); + } + }); + final long f = from.getValue(); final long t = to.getValue(); Validate.isTrue(f == t || Long.signum(step) == Long.signum(t - f), "Will never reach '%s' from '%s' using step %s", t, f, step); - - if (from.getBoundType() == BoundType.CLOSED) { - this.currentValue = f; - } else { - this.currentValue = f + step; - } } /** @@ -164,43 +159,47 @@ public final class LongRange extends Num this(new Endpoint<Long>(from, leftBoundType), new Endpoint<Long>(to, rightBoundType), step); } - // iterable, iterator methods + // iterable // --------------------------------------------------------------- + /** * {@inheritDoc} */ - public boolean hasNext() { - final long to = this.rightEndpoint.getValue(); - if (step < 0) { - if (this.rightEndpoint.getBoundType() == BoundType.CLOSED) { - return this.currentValue >= to; - } else { - return this.currentValue > to; + protected Iterator<Long> createIterator() { + return new Iterator<Long>() { + private long currentValue; + + { + currentValue = leftEndpoint.getValue(); + + if (leftEndpoint.getBoundType() == BoundType.OPEN) { + this.currentValue += step; + } } - } else { - if (this.rightEndpoint.getBoundType() == BoundType.CLOSED) { - return this.currentValue <= to; - } else { - return this.currentValue < to; + + public void remove() { + throw new UnsupportedOperationException(); } - } - } - /** - * {@inheritDoc} - */ - public Long next() { - final long step = this.getStep(); - final long r = this.currentValue; - this.currentValue += step; - return Long.valueOf(r); - } + public Long next() { + final long step = getStep(); + final long r = currentValue; + currentValue += step; + return Long.valueOf(r); + } - /** - * {@inheritDoc} - */ - public Iterator<Long> iterator() { - return this; + public boolean hasNext() { + final int cmp = Long.compare(currentValue, rightEndpoint.getValue()); + + if (cmp == 0) { + return rightEndpoint.getBoundType() == BoundType.CLOSED; + } + if (step > 0L) { + return cmp < 0; + } + return cmp > 0; + } + }; } } Modified: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/NumericRange.java URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/NumericRange.java?rev=1541636&r1=1541635&r2=1541636&view=diff ============================================================================== --- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/NumericRange.java (original) +++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/NumericRange.java Wed Nov 13 17:54:37 2013 @@ -16,6 +16,8 @@ */ package org.apache.commons.functor.range; +import org.apache.commons.functor.BinaryFunction; + /** * A base class for numeric ranges. The elements within this range must be a * <b>Number</b> and <b>Comparable</b>. @@ -29,40 +31,17 @@ package org.apache.commons.functor.range * @since 0.1 * @version $Revision$ $Date$ */ -public abstract class NumericRange<T extends Number & Comparable<?>> extends AbstractRange<T, T> { +public abstract class NumericRange<T extends Number & Comparable<T>> extends AbstractRange<T, T> { /** - * Construct a new {@link NumericRange}. + * Construct a new {@link NumericRange}.T * @param leftEndpoint left endpoint * @param rightEndpoint right endpoint * @param step increment step + * @param nextValue function to implement the taking of a step */ - protected NumericRange(Endpoint<T> leftEndpoint, Endpoint<T> rightEndpoint, T step) { - super(leftEndpoint, rightEndpoint, step); - } - - /** - * {@inheritDoc} - */ - public boolean isEmpty() { - double leftValue = this.getLeftEndpoint().getValue().doubleValue(); - double rightValue = this.getRightEndpoint().getValue().doubleValue(); - boolean closedLeft = this.getLeftEndpoint().getBoundType() == BoundType.CLOSED; - boolean closedRight = this.getRightEndpoint().getBoundType() == BoundType.CLOSED; - if (!closedLeft && !closedRight - && this.getLeftEndpoint().equals(this.getRightEndpoint())) { - return true; - } - double step = this.getStep().doubleValue(); - if (step > 0.0) { - double firstValue = closedLeft ? leftValue : leftValue + step; - return closedRight ? firstValue > rightValue - : firstValue >= rightValue; - } else { - double firstValue = closedLeft ? leftValue : leftValue + step; - return closedRight ? firstValue < rightValue - : firstValue <= rightValue; - } + protected NumericRange(Endpoint<T> leftEndpoint, Endpoint<T> rightEndpoint, T step, BinaryFunction<T, T, T> nextValue) { + super(leftEndpoint, rightEndpoint, step, nextValue); } /** Modified: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/Range.java URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/Range.java?rev=1541636&r1=1541635&r2=1541636&view=diff ============================================================================== --- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/Range.java (original) +++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/Range.java Wed Nov 13 17:54:37 2013 @@ -17,8 +17,6 @@ package org.apache.commons.functor.range; import java.util.Collection; -import java.util.Iterator; - /** * Represent an interval of elements that varies from the <b>left limit</b> @@ -37,7 +35,7 @@ import java.util.Iterator; * @since 1.0 * @version $Revision$ $Date$ */ -public interface Range<T extends Comparable<?>, S extends Comparable<?>> extends Iterable<T>, Iterator<T> { +public interface Range<T extends Comparable<?>, S> extends Iterable<T> { /** * Default left bound type. Modified: commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/example/kata/two/TestBinaryChop.java URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/example/kata/two/TestBinaryChop.java?rev=1541636&r1=1541635&r2=1541636&view=diff ============================================================================== --- commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/example/kata/two/TestBinaryChop.java (original) +++ commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/example/kata/two/TestBinaryChop.java Wed Nov 13 17:54:37 2013 @@ -20,7 +20,6 @@ import static org.junit.Assert.assertEqu import java.util.ArrayList; import java.util.Collections; -import java.util.Iterator; import java.util.List; import org.apache.commons.functor.NullaryFunction; @@ -28,6 +27,7 @@ import org.apache.commons.functor.Nullar import org.apache.commons.functor.NullaryProcedure; import org.apache.commons.functor.core.algorithm.RecursiveEvaluation; import org.apache.commons.functor.core.algorithm.UntilDo; +import org.apache.commons.functor.generator.loop.IteratorToGeneratorAdapter; import org.apache.commons.functor.range.IntegerRange; import org.junit.Test; @@ -104,10 +104,9 @@ public class TestBinaryChop { assertEquals(-1, chopper.find(6, new int[] { 1, 3, 5, 7 })); assertEquals(-1, chopper.find(8, new int[] { 1, 3, 5, 7 })); - List<Integer> largeList = new ArrayList<Integer>(); - Iterator<Integer> ints = new IntegerRange(0, 100001); - while(ints.hasNext()) - largeList.add(ints.next()); + final List<Integer> largeList = + IteratorToGeneratorAdapter.adapt(new IntegerRange(0, 100001)).to(new ArrayList<Integer>()); + assertEquals(-1, chopper.find(new Integer(-5), largeList)); assertEquals(100000, chopper.find(new Integer(100000), largeList)); assertEquals(0, chopper.find(new Integer(0), largeList)); Modified: commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/loop/TestIteratorToGeneratorAdapter.java URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/loop/TestIteratorToGeneratorAdapter.java?rev=1541636&r1=1541635&r2=1541636&view=diff ============================================================================== --- commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/loop/TestIteratorToGeneratorAdapter.java (original) +++ commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/loop/TestIteratorToGeneratorAdapter.java Wed Nov 13 17:54:37 2013 @@ -69,7 +69,7 @@ public class TestIteratorToGeneratorAdap @Test public void testAdaptNull() { - assertNull(IteratorToGeneratorAdapter.adapt(null)); + assertNull(IteratorToGeneratorAdapter.adapt((Iterator<?>) null)); } @Test Modified: commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/range/TestLongRange.java URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/range/TestLongRange.java?rev=1541636&r1=1541635&r2=1541636&view=diff ============================================================================== --- commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/range/TestLongRange.java (original) +++ commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/range/TestLongRange.java Wed Nov 13 17:54:37 2013 @@ -25,6 +25,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Iterator; import java.util.List; import org.apache.commons.functor.BaseFunctorTest; @@ -81,16 +82,18 @@ public class TestLongRange extends BaseF // generates a collection of Integers from 0 (inclusive) to 10 (exclusive) { LongRange range = Ranges.longRange(0, 10); + Iterator<Long> iter = range.iterator(); for (int i=0;i<10;i++) { - assertEquals(new Long(i), range.next()); + assertEquals(new Long(i), iter.next()); } } // generates a collection of Integers from 10 (inclusive) to 0 (exclusive) { LongRange range = Ranges.longRange(10, 0); + Iterator<Long> iter = range.iterator(); for (int i=10;i>0;i--) { - assertEquals(new Long(i), range.next()); + assertEquals(new Long(i), iter.next()); } } }