Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why java numbers aren't iterable

I can't keep wondering why I can't write something like that:

for (int i : 3) {
  System.out.println(i);
}

to print out:

0
1
2

I mean, 3 could be auto-boxed into an Integer, which could be Iterable.
I know, I've selected the first element to be 0, but I assume it's the common case and that it could facilitate counting down with such ForEach construct.

like image 254
Asaf Avatar asked May 02 '11 15:05

Asaf


4 Answers

this is kind of stupid, but you could write something like this:

    for (int i : iter(3)) {
        System.out.println(i);  // 0, 1, 2
    }

    for (int i : iter(-5)) {
        System.out.println(i);  // 0, -1, -2, -3, -4
    }

    for (int i : iter(1, 7)) {
        System.out.println(i);  // 1, 2, 3, 4, 5, 6
    }

if you would statically import method:

import static your.package.IterUtil.iter;

from this custom class:

public class IterUtil {

    public static Iterable<Integer> iter(int to) {
        return new IntIterable(0, to);
    }

    public static Iterable<Integer> iter(int from, int to) {
        return new IntIterable(from, to);
    }


    private static class IntIterable implements Iterable<Integer> {

        private int start;
        private int end;

        private IntIterable(int start, int end) {
            this.start = start;
            this.end = end;
        }

        @Override
        public Iterator<Integer> iterator() {
            return new Iterator<Integer>() {
                private int actual = start;

                @Override
                public boolean hasNext() {
                    return actual != end;
                }

                @Override
                public Integer next() {
                    int value = actual;

                    if (actual < end) {
                        actual++;
                    } else if (actual > end) {
                        actual--;
                    }

                    return value;
                }

                @Override
                public void remove() {
                    // do nothing
                }
            };
        }
    }
}
like image 163
Matej Tymes Avatar answered Oct 01 '22 16:10

Matej Tymes


Because a number is not a range. Converting a number to a range is ambiguous. There is nothing stopping you from writing a Range class that is iterable, for example

public class IntegerRange implements Iterable<Integer> {
  private final int _fromInclusive;
  private final int _toExclusive;

  public IntegerRange(int fromInclusive, int toExclusive) {
    _fromInclusive = fromInclusive;
    _toExclusive = toExclusive;
  }

  public Iterator<Integer> iterator() {
    return new Iterator<Integer>() {
      int c = _fromInclusive;
      public boolean hasNext() {
        return c < _toExclusive;
      }

      public Integer next() {
        if (c >= _toExclusive) {
          throw new NoSuchElementException();
        }
        return c++;
      }

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

Note that with such an approach, you can easily add features like specifying the increment, whether range is inclusive on both sides, etc.

like image 33
Dilum Ranatunga Avatar answered Oct 01 '22 16:10

Dilum Ranatunga


You iterate over collections of Objects. and Integer is a single Object there is nothing to iterate over. However, you could just do this:

for(int i=0;i<number;i++)
like image 43
John Kane Avatar answered Oct 01 '22 17:10

John Kane


In java, the foreach loop only iterates over either arrays, or collections that implement the Iterable interface, which the wrapper type Integer does not.

But it makes sense when you think about it. What does "for each integer i in 3, do this" mean? How many integers are in 3? Do we start at zero, so there are 4 integers (0,1,2,3)? Do we start at 1? Do we necessarily always step by one?

If you want to emulate that behavior, TheOtherGuy's answer will work, but a straightforward for-loop is probably even better.

like image 21
Zach L Avatar answered Oct 01 '22 16:10

Zach L