Repository: commons-math Updated Branches: refs/heads/master 8ed2209b1 -> fa1aa44c7
MATH-1286 New "Range" inner class that holds a field with the number of elements of the range. An instance of this class replaces the anonymous class returned by the "range" method. Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/fa1aa44c Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/fa1aa44c Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/fa1aa44c Branch: refs/heads/master Commit: fa1aa44c7623fb2142e588c59eaf56db7bc237eb Parents: 8ed2209 Author: Gilles <[email protected]> Authored: Sat Oct 31 15:36:35 2015 +0100 Committer: Gilles <[email protected]> Committed: Sat Oct 31 15:36:35 2015 +0100 ---------------------------------------------------------------------- src/changes/changes.xml | 3 + .../commons/math4/util/IntegerSequence.java | 74 ++++++++++++++++---- .../commons/math4/util/IntegerSequenceTest.java | 47 +++++++++++-- 3 files changed, 102 insertions(+), 22 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-math/blob/fa1aa44c/src/changes/changes.xml ---------------------------------------------------------------------- diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 55a8fcb..d31605c 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -54,6 +54,9 @@ If the output is not quite correct, check for invisible trailing spaces! </release> <release version="4.0" date="XXXX-XX-XX" description=""> + <action dev="erans" type="add" issue="MATH-1286"> + New "Range" inner class of "o.a.c.m.util.IntegerSequence". + </action> <action dev="oertl" type="fix" issue="MATH-1285" due-to="Pim van der Hoorn "> <!-- backported to 3.6 --> Updated reference in ZipfDistribution's javadoc. </action> http://git-wip-us.apache.org/repos/asf/commons-math/blob/fa1aa44c/src/main/java/org/apache/commons/math4/util/IntegerSequence.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math4/util/IntegerSequence.java b/src/main/java/org/apache/commons/math4/util/IntegerSequence.java index 1a16b0c..233ce3a 100644 --- a/src/main/java/org/apache/commons/math4/util/IntegerSequence.java +++ b/src/main/java/org/apache/commons/math4/util/IntegerSequence.java @@ -42,8 +42,8 @@ public class IntegerSequence { * @param end Last value of the range. * @return a range. */ - public static Iterable<Integer> range(int start, - int end) { + public static Range range(int start, + int end) { return range(start, end, 1); } @@ -58,19 +58,63 @@ public class IntegerSequence { * @param step Increment. * @return a range. */ - public static Iterable<Integer> range(final int start, - final int max, - final int step) { - return new Iterable<Integer>() { - /** {@inheritDoc} */ - @Override - public Iterator<Integer> iterator() { - return Incrementor.create() - .withStart(start) - .withMaximalCount(max + (step > 0 ? 1 : -1)) - .withIncrement(step); - } - }; + public static Range range(final int start, + final int max, + final int step) { + return new Range(start, max, step); + } + + /** + * Generates a sequence of integers. + */ + public static class Range implements Iterable<Integer> { + /** Number of integers contained in this range. */ + private final int size; + /** First value. */ + private final int start; + /** Final value. */ + private final int max; + /** Increment. */ + private final int step; + + /** + * Creates a sequence \( a_i, i < 0 <= n \) + * where \( a_i = start + i * step \) + * and \( n \) is such that \( a_n <= max \) and \( a_{n+1} > max \). + * + * @param start First value of the range. + * @param max Last value of the range that satisfies the above + * construction rule. + * @param step Increment. + */ + public Range(int start, + int max, + int step) { + this.start = start; + this.max = max; + this.step = step; + + final int s = (max - start) / step + 1; + this.size = s < 0 ? 0 : s; + } + + /** + * Gets the number of elements contained in the range. + * + * @return the size of the range. + */ + public int size() { + return size; + } + + /** {@inheritDoc} */ + @Override + public Iterator<Integer> iterator() { + return Incrementor.create() + .withStart(start) + .withMaximalCount(max + (step > 0 ? 1 : -1)) + .withIncrement(step); + } } /** http://git-wip-us.apache.org/repos/asf/commons-math/blob/fa1aa44c/src/test/java/org/apache/commons/math4/util/IntegerSequenceTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/math4/util/IntegerSequenceTest.java b/src/test/java/org/apache/commons/math4/util/IntegerSequenceTest.java index d1a6764..25eec4f 100644 --- a/src/test/java/org/apache/commons/math4/util/IntegerSequenceTest.java +++ b/src/test/java/org/apache/commons/math4/util/IntegerSequenceTest.java @@ -27,17 +27,40 @@ import org.junit.Test; */ public class IntegerSequenceTest { @Test + public void testRangeMultipleIterations() { + // Check that we can iterate several times using the same instance. + final int start = 1; + final int max = 7; + final int step = 2; + + final List<Integer> seq = new ArrayList<Integer>(); + final IntegerSequence.Range r = IntegerSequence.range(start, max, step); + + final int numTimes = 3; + for (int n = 0; n < numTimes; n++) { + seq.clear(); + for (Integer i : r) { + seq.add(i); + } + Assert.assertEquals(4, seq.size()); + Assert.assertEquals(seq.size(), r.size()); + } + } + + @Test public void testIncreasingRange() { final int start = 1; final int max = 7; final int step = 2; final List<Integer> seq = new ArrayList<Integer>(); - for (Integer i : IntegerSequence.range(start, max, step)) { + final IntegerSequence.Range r = IntegerSequence.range(start, max, step); + for (Integer i : r) { seq.add(i); } Assert.assertEquals(4, seq.size()); + Assert.assertEquals(seq.size(), r.size()); for (int i = 0; i < seq.size(); i++) { Assert.assertEquals(start + i * step, seq.get(i).intValue()); } @@ -50,11 +73,13 @@ public class IntegerSequenceTest { final int step = 2; final List<Integer> seq = new ArrayList<Integer>(); - for (Integer i : IntegerSequence.range(start, max, step)) { + final IntegerSequence.Range r = IntegerSequence.range(start, max, step); + for (Integer i : r) { seq.add(i); } Assert.assertEquals(5, seq.size()); + Assert.assertEquals(seq.size(), r.size()); for (int i = 0; i < seq.size(); i++) { Assert.assertEquals(start + i * step, seq.get(i).intValue()); } @@ -67,11 +92,13 @@ public class IntegerSequenceTest { final int step = -3; final List<Integer> seq = new ArrayList<Integer>(); - for (Integer i : IntegerSequence.range(start, max, step)) { + final IntegerSequence.Range r = IntegerSequence.range(start, max, step); + for (Integer i : r) { seq.add(i); } Assert.assertEquals(7, seq.size()); + Assert.assertEquals(seq.size(), r.size()); for (int i = 0; i < seq.size(); i++) { Assert.assertEquals(start + i * step, seq.get(i).intValue()); } @@ -84,11 +111,13 @@ public class IntegerSequenceTest { final int step = -1; final List<Integer> seq = new ArrayList<Integer>(); - for (Integer i : IntegerSequence.range(start, max, step)) { + final IntegerSequence.Range r = IntegerSequence.range(start, max, step); + for (Integer i : r) { seq.add(i); } Assert.assertEquals(1, seq.size()); + Assert.assertEquals(seq.size(), r.size()); Assert.assertEquals(start, seq.get(0).intValue()); } @@ -110,14 +139,16 @@ public class IntegerSequenceTest { @Test public void testEmptyRange() { final int start = 2; - final int end = 1; + final int end = 0; final List<Integer> seq = new ArrayList<Integer>(); - for (Integer i : IntegerSequence.range(start, end)) { + final IntegerSequence.Range r = IntegerSequence.range(start, end); + for (Integer i : r) { seq.add(i); } Assert.assertEquals(0, seq.size()); + Assert.assertEquals(seq.size(), r.size()); } @Test @@ -127,11 +158,13 @@ public class IntegerSequenceTest { final int step = -1; final List<Integer> seq = new ArrayList<Integer>(); - for (Integer i : IntegerSequence.range(start, max, step)) { + final IntegerSequence.Range r = IntegerSequence.range(start, max, step); + for (Integer i : r) { seq.add(i); } Assert.assertEquals(0, seq.size()); + Assert.assertEquals(seq.size(), r.size()); } @Test(expected=MaxCountExceededException.class)
