Для функции диапазона типа Python

Мне было интересно, есть ли в Java функция, подобная функции диапазона python.

range(4)

и он вернет

[0,1,2,3]

Это был простой способ сделать для расширенных циклов. Было бы здорово сделать это на Java, потому что это упростило бы циклы. Возможно ли это?

Ответ 1

Java 8 добавила IntStream (похож на apache commons IntRange), поэтому теперь вам не нужна внешняя библиотека.

IntStream.range(0, 3).forEachOrdered(n -> {
    //work on n here
});

forEach можно использовать вместо forEachOrdered, если порядок не важен.

Ответ 2

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

У вас есть такой класс:

class Range implements Iterable<Integer> {

    private int limit;

    public Range(int limit) {
        this.limit = limit;
    }

    @Override
    public Iterator<Integer> iterator() {
        final int max = limit;
        return new Iterator<Integer>() {

            private int current = 0;

            @Override
            public boolean hasNext() {
                return current < max;
            }

            @Override
            public Integer next() {
                if (hasNext()) {
                    return current++;   
                } else {
                    throw new NoSuchElementException("Range reached the end");
                }
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException("Can't remove values from a Range");
            }
        };
    }
}

и вы можете просто использовать его следующим образом:

    for (int i : new Range(5)) {
        System.out.println(i);
    }

вы можете его повторно использовать:

    Range range5 = new Range(5);

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

Как отметил Генри Кейтер в комментарии ниже, мы могли бы добавить следующий метод в класс Range (или где-нибудь еще):

public static Range range(int max) {
    return new Range(max);
}

а затем в других классах мы можем

import static package.name.Range.range;

и просто вызовите

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

Ответ 3

Используйте Apache Commons Lang:

new IntRange(0, 3).toArray();

Я бы обычно не выступал за введение внешних библиотек для чего-то такого простого, но Apache Commons настолько широко используется, что вы, вероятно, уже имеете его в своем проекте!

Изменить: я знаю, что это не обязательно так просто или быстро, как цикл for, но это хороший бит синтаксического сахара, который делает намерение понятным.

Изменить: см. @zengr ответ с помощью IntStream в Java 8.

Ответ 4

Um... for (int i = 0; i < k; i++)? Вы не должны писать расширенные для циклов весь день, вы знаете, хотя они классные...

И только ради аргумента:

for (int i : range(k)) char count: 22

for (int i = 0; i < k; i++) char count: 27

Дисконтирование реализации range, это псевдо четность.

Ответ 5

Если вы действительно хотите получить эквивалентный результат на Java, вам нужно будет сделать еще одну работу:

public int[] range(int start, int end, int step) {
    int n = (int) Math.ceil((end-start)/(double)step);
    int[] arange = new int[n];
    for (int i = 0; i < n; i++)
        arange[i] = i*step+start;
    return arange;
}

Теперь range(0, 4, 1) вернет ожидаемое значение, как и Python: [0, 1, 2, 3]. К сожалению, в Java нет более простого способа, это не очень выразительный язык, как Python.

Ответ 6

Недоступно, что это правда. Но вы делаете статический метод и используете его -

public static int[] range(int index){
    int[] arr = new int[index];
    for(int i=0;i<index;i++){
        arr[i]=i;
    }
    return arr;
}

Ответ 7

Нет эквивалента Java для функции range, но существует улучшенный for-loop:

for (String s : strings) {
    // Do stuff
}

Вы также можете свернуть свою собственную функцию range, если вы действительно привязаны к синтаксису, но это кажется немного глупым.

public static int[] range(int length) {
    int[] r = new int[length];
    for (int i = 0; i < length; i++) {
        r[i] = i;
    }
    return r;
}

// ...

String s;
for (int i : range(arrayOfStrings.length)) {
    s = arrayOfStrings[i];
    // Do stuff
}

Ответ 8

Насколько я знаю, в java нет эквивалентной функции. Но вы можете написать сами:

public static int[] range(int n) {
    int[] ans = new int[n];
    int i;
    for(i = 0; i < n; i++) {
        ans[i] = i;
    }
    return ans;
}