patternjavaMinor
Using a Pythonesque range() generator function with the Java foreach loop
Viewed 0 times
thepythonesquewithrangeloopfunctionjavageneratorusingforeach
Problem
Now that we have the nice new
I like the way Python has a
I have written a
```
package highland.mark;
import java.util.Iterator;
/**
* A class to enable java's 'foreach' loop to accept a range.
*
* This allows replacing the C style:
*
*
*
* for (int i = 0; i
*
*
* with:
*
*
*
* for (int i : range(10)) {...}
*
*
*
* Three versions of range() are provided allowing combinations of start, end,
* and step.
*
* @author Mark Thomas
* @version 1.0
*/
public final class Range implements Iterator, Iterable {
/**
* The next integer to be returned by the iterator.
*
*/
private int next;
/**
* The last integer to be returned will be (next - 1).
*/
private final int to;
/**
* The increment added to the value of next after each iteration.
*/
private final int step;
/**
* A Method to be used with the java 'foreach' loop.
*
* Usage:
*
*
*
* import static highland.mark.Range.range;
* ...
* for (int i : range(from, to, step)) {...}
*
*
*
* @param from
* : int, first value returned.
* @param to
* : int, one more than last value returned.
* @param step
* : int, increment for each iteration (may be negative so long
* as (to .
* @return An Iterable which supplies an Iterator which,
* on each iteration, returns integers from from to
* (to - 1) incrementing by step each
* time.
* @throws IllegalArgumentException
* if step == 0 or step is the wrong
* sign.
*/
public static Iterable range(int from, int to, int step)
foreach loop in Java, the old-style loop looks ugly be comparison.I like the way Python has a
range() generator that allows the foreach construct to iterate over a range of integers.I have written a
Range class which allows this. Please provide comments. ```
package highland.mark;
import java.util.Iterator;
/**
* A class to enable java's 'foreach' loop to accept a range.
*
* This allows replacing the C style:
*
*
*
* for (int i = 0; i
*
*
* with:
*
*
*
* for (int i : range(10)) {...}
*
*
*
* Three versions of range() are provided allowing combinations of start, end,
* and step.
*
* @author Mark Thomas
* @version 1.0
*/
public final class Range implements Iterator, Iterable {
/**
* The next integer to be returned by the iterator.
*
*/
private int next;
/**
* The last integer to be returned will be (next - 1).
*/
private final int to;
/**
* The increment added to the value of next after each iteration.
*/
private final int step;
/**
* A Method to be used with the java 'foreach' loop.
*
* Usage:
*
*
*
* import static highland.mark.Range.range;
* ...
* for (int i : range(from, to, step)) {...}
*
*
*
* @param from
* : int, first value returned.
* @param to
* : int, one more than last value returned.
* @param step
* : int, increment for each iteration (may be negative so long
* as (to .
* @return An Iterable which supplies an Iterator which,
* on each iteration, returns integers from from to
* (to - 1) incrementing by step each
* time.
* @throws IllegalArgumentException
* if step == 0 or step is the wrong
* sign.
*/
public static Iterable range(int from, int to, int step)
Solution
For the most part, this appears to be neat, and well structured.
There is a significant bug, though:
For example, the following code should print the numbers 1 to 10 twice....
Your code will only print them once.
The fix for this is to store the
EDIT: I should point out this:
There is a significant bug, though:
Iterableimplies aniterator()method. Each time you call thatiterator()method you should get a new instance of an interator, not an 'expired' instance.
For example, the following code should print the numbers 1 to 10 twice....
Range onetoten = Range.range(1, 10, 1);
for (Integer i : onetoten) {
System.out.println(i);
}
for (Integer i : onetoten) {
System.out.println(i);
}Your code will only print them once.
The fix for this is to store the
from value as well as the to and the step, and to then return a duplicate Range in the iterator() method.EDIT: I should point out this:
IntStream.rangeClosed() (Java8)IntStream.rangeClosed(1, 10).forEach(i -> System.out.println(i));Code Snippets
Range onetoten = Range.range(1, 10, 1);
for (Integer i : onetoten) {
System.out.println(i);
}
for (Integer i : onetoten) {
System.out.println(i);
}IntStream.rangeClosed(1, 10).forEach(i -> System.out.println(i));Context
StackExchange Code Review Q#45535, answer score: 8
Revisions (0)
No revisions yet.