Skip to content

Instantly share code, notes, and snippets.

@colin-haber
Created June 14, 2012 06:09
Show Gist options
  • Select an option

  • Save colin-haber/2928256 to your computer and use it in GitHub Desktop.

Select an option

Save colin-haber/2928256 to your computer and use it in GitHub Desktop.
package com.n1nja.utils;
import java.util.Iterator;
/**
* Allows for Python-like {@code foreach} loop iteration with
* {@link java.lang.Integer Integer}s. Use as follows.
* <pre>
* for ({@link java.lang.Integer Integer} l : new Range());
* </pre>
* @author Colin Haber
* @version 0.1.0
*/
public class Range implements Iterable<Integer> {
/**
* The default {@linkplain #start starting value} for {@link Range}s that
* do not explicitly define one.
* @since 0.1.0
* @see #Range(Integer)
*/
private static Integer DEFAULT_START = 0;
/**
* The default {@linkplain #step step size} for {@link Range}s that do not
* explicitly define one.
* @since 0.1.0
* @see #Range(Integer)
* @see #Range(Integer, Integer)
*/
private static Integer DEFAULT_STEP = 1;
/**
* The {@link Range}'s starting value, inclusive.
* @since 0.0.0
*/
private final Integer start;
/**
* The {@link Range}'s ending value, non-inclusive.
* @since 0.0.0
*/
private final Integer end;
/**
* The {@link Range}'s step (or interval) size.
* @since 0.0.0
*/
private final Integer step;
/**
* Creates a {@link Range} from {@code 0}, inclusive, to {@code count},
* non-inclusive, with a {@linkplain #step} size of {@code 1}.
* @since 0.0.0
* @param count the {@link #end} value for this {@link Range},
* non-inclusive
*/
public Range(Integer count) {
this(Range.DEFAULT_START, count);
}
/**
* Creates a {@link Range} from {@code start}, inclusive, to {@code end},
* non-inclusive, with a {@linkplain #step} size of {@code 1}.
* @since 0.0.0
* @param start the {@link #start} value for this {@link Range}, inclusive
* @param end the {@link #end} value for this {@link Range}, non-inclusive
*/
public Range(Integer start, Integer end) {
this(start, end, Range.DEFAULT_STEP);
}
/**
* Creates a {@link Range} from {@code start}, inclusive, to {@code end},
* non-inclusive, with a {@linkplain #step} size of {@code step}.
* @since 0.0.0
* @param start the {@link #start} value for this {@link Range}, inclusive
* @param end the {@link #end} value for this {@link Range}, non-inclusive
* @param step the {@link #step} size for this {@link Range}
*/
public Range(Integer start, Integer end, Integer step) {
this.start = start;
this.end = end;
this.step = step;
}
@Override
public Iterator<Integer> iterator() {
final Integer startVal = this.start;
final Integer endVal = this.end;
final Integer stepSize = this.step;
return new Iterator<Integer>() {
private final Integer start = startVal;
private final Integer end = endVal;
private final Integer step = stepSize;
private Integer index;
{
if ((this.end - this.start != 0) && (Math.signum(this.end - this.start) != Math.signum(this.step))) {
throw new IllegalArgumentException("Infinite looping statement detected.");
}
this.index = 0;
}
@Override
public boolean hasNext() {
return ((this.start < this.end) && (this.start + (this.step * this.index) < this.end) || ((this.start > this.end) && (this.start + (this.step * this.index) > this.end)));
}
@Override
public synchronized Integer next() {
Integer next = null;
if (this.hasNext()) {
next = this.start + (this.step * this.index);
this.index++;
}
return next;
}
@Override
public void remove() {
throw new UnsupportedOperationException(this.getClass().getSimpleName() + " does not support remove().");
}
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment