xrange

わざわざ配列を作ってしまうのは非効率だよなー、ということで xrange 版。いやまぁ、boxing と unboxing のコストがかかるけどねー。

import java.util.Iterator;

public class XRange implements Iterable<Integer> {
    private static class XRangeIterator implements Iterator<Integer> {
        private int start;
        private int stop;
        private int step;
        private int current;

        public XRangeIterator(int start, int stop, int step) {
            if (step == 0) {
                throw new IllegalArgumentException("step must be non-zero");
            }

            this.start = start;
            this.stop = stop;
            this.step = step;

            this.current = this.start;
        }

        @Override
        public boolean hasNext() {
            if (step > 0) {
                return current < stop;
            } else {
                return current > stop;
            }
        }

        @Override
        public Integer next() {
            int v = current;
            current += step;
            return v;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }

    private int start;
    private int stop;
    private int step;

    public XRange(int start, int stop, int step) {
        this.start = start;
        this.stop = stop;
        this.step = step;
    }

    @Override
    public Iterator<Integer> iterator() {
        return new XRangeIterator(start, stop, step);
    }

    public int[] toArray() {
        int size = Math.max((stop - start) / step, 0);
        int[] array = new int[size];
        int i = 0;
        for (int v : this) {
            array[i++] = v;
        }
        return array;
    }

    public static XRange xrange(int start, int stop, int step) {
        return new XRange(start, stop, step);
    }

    public static XRange xrange(int start, int stop) {
        return new XRange(start, stop, 1);
    }

    public static XRange xrange(int stop) {
        return new XRange(0, stop, 1);
    }

    public static XRange fromTo(int from, int to) {
        return new XRange(from, to + 1, 1);
    }
}