Почему числа java не повторяемы - PullRequest
7 голосов
/ 02 мая 2011

Я не могу продолжать задаваться вопросом, почему я не могу написать что-то подобное:

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

распечатать:

0
1
2

Я имею в виду, 3 может быть автоматически упакован в Integer, который может быть Iterable.
Я знаю, что я выбрал первый элемент 0, но я предполагаю, что это общий случай, и он может облегчить обратный отсчет с помощью такой конструкции ForEach.

Ответы [ 7 ]

10 голосов
/ 02 мая 2011

это немного глупо, но вы могли бы написать что-то вроде этого:

    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
    }

, если бы вы статически импортировали метод:

import static your.package.IterUtil.iter;

из этого пользовательского класса:

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
                }
            };
        }
    }
}
9 голосов
/ 02 мая 2011

Потому что число не является диапазоном. Преобразование числа в диапазон неоднозначно. Ничто не мешает вам написать класс Range, который является повторяемым, например

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();
      }
    };
  }
}

Обратите внимание, что при таком подходе вы можете легко добавлять такие функции, как указание приращения, включение диапазона с обеих сторон и т. Д.

4 голосов
/ 02 мая 2011

В java цикл foreach выполняет итерацию только по массивам или по коллекциям, которые реализуют интерфейс Iterable , тип оболочки которого Integer нет.

Но это имеет смысл, когда вы думаете об этом. Что значит «для каждого целого числа i в 3, сделать это»? Сколько целых чисел равно в 3? Мы начинаем с нуля, так что есть 4 целых числа (0,1,2,3)? Мы начинаем с 1? Обязательно ли мы всегда шаг за шагом?

Если вы хотите эмулировать это поведение, ответ TheOtherGuy сработает, но простой цикл for, вероятно, еще лучше.

4 голосов
/ 02 мая 2011

Вы перебираете коллекции объектов.и Integer - это один объект, которому нечего итерировать.Тем не менее, вы можете просто сделать это:

for(int i=0;i<number;i++)
4 голосов
/ 02 мая 2011

В синтаксисе for(x : c) c должен быть Iterable;3 нет.вы можете сделать

    for (int i : new int[]{0,1,2}) {
          System.out.println(i);
     }
2 голосов
/ 02 мая 2011

Как уже отмечали другие, Java for-each перебирает массив или коллекцию.«3» - это не массив или коллекция, это одно значение.Если Java допускает предложенную вами конструкцию, единственной последовательной реализацией будет «итерация» по одному значению 3. То есть:

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

будет выводить:

3

Что не кажется очень полезным, и, возможно, именно поэтому они не реализовали его.

Ваш вопрос предполагает, что одно значение, такое как "3", подразумевает диапазон.Но почему вы предполагаете {0,1,2,3}?Почему бы не {1,2,3}?Или {-3, -2, -1, 0, 1, 2, 3}?Или {0,5, 1,0, 1,5, 2,0, 2,5, 3}?Или буквально бесконечное число других возможных вариантов.

Чтобы сделать это конкретным, вам нужно указать начальное значение, конечное значение и приращение.Хм, может быть, мы могли бы придумать такую ​​запись:

for (int i=0,3,1)

Но это все еще неоднозначно.Непонятно, хотим ли мы продолжать до i == 3 или до последнего значения <3.И нам, вероятно, нужно отличать приращение плюс от вложения минус.Так как насчет этого, более гибкая запись: </p>

for (int i=0; i<=3; i=i+1)

Ой, подождите, это уже поддерживается.: -)

1 голос
/ 02 мая 2011

Number имеет не целочисленные подклассы, такие как Float и BigDecimal, поэтому не имеет смысла реализовывать Iterable <Integer> для Number.Хотя Integer и Long реализуют Iterable <Integer|Long>, было бы неплохо.

...