Java: еквівалент діапазону Python (int, int)?


99

Чи має Java еквівалент range(int, int)методу Python ?


Ви маєте на увазі діапазон Python 2.x, який повертає список, або діапазон Python 3.x, який повертає ітератор (еквівалентний xx 2.x)? Перший порівняно простий у виконанні, як це робили інші нижче, але версія ітератора дещо складніша.
Дейв Кірбі


Для діапазону будь-яких Comparableх см цей відповідь
c0der

Для діапазону з кроком дивіться це
Славомір Ленарт

Відповіді:


27

Guava також пропонує щось подібне до Python range:

Range.closed(1, 5).asSet(DiscreteDomains.integers());

Ви також можете реалізувати досить простий ітератор, щоб зробити те ж саме, використовуючи AbstractIterator Guava:

return new AbstractIterator<Integer>() {
  int next = getStart();

  @Override protected Integer computeNext() {
    if (isBeyondEnd(next)) {
      return endOfData();
    }
    Integer result = next;
    next = next + getStep();
    return result;
  }
};

6
Мені б хотілося, щоб я це бачив ще до того, як застосував власний загальний діапазон. Це приємно, але все ж ще одне нагадування про те, як незграбну Java можна порівняти з більш функціональними мовами.
z7sg Ѫ

14
Range#asSetначебто, застаріла. Тепер вам потрібно зробити це:ContiguousSet.create(Range.closed(low, high), DiscreteDomain.integers())
Chthonic Project

яку бібліотеку мені потрібно імпортувати, щоб використовувати це?
tgabb

У Java 8, IntStream і LongStream мають діапазон методів і діапазонЗакрито.
Жозе Мануель Гомес Альварес

225

Старе запитання, нова відповідь (для Java 8)

    IntStream.range(0, 10).forEach(
        n -> {
            System.out.println(n);
        }
    );

або із посиланнями на методи:

IntStream.range(0, 10).forEach(System.out::println);

1
Який пакет? як це імпортувати?
Джастін Томас

6
@Justin Це особливість мови Java 8.
Цафрір


16

Оскільки Guava 15.0, Range.asSet () був застарілим і його планується видалити у версії 16. Використовуйте наступне:

ContiguousSet.create(Range.closed(1, 5), DiscreteDomain.integers());

15

Я працюю над невеликою бібліотекою Java утилітів під назвою Jools , і вона містить клас, Rangeякий забезпечує необхідну функціональність (є JAR, який можна завантажити).
Конструктори є або Range(int stop), Range(int start, int stop)або Range(int start, int stop, int step)(подібні до циклу for), і ви можете або повторити його, який використовував ледачу оцінку, або ви можете використовувати його toList()метод для явного отримання списку діапазонів.

for (int i : new Range(10)) {...} // i = 0,1,2,3,4,5,6,7,8,9

for (int i : new Range(4,10)) {...} // i = 4,5,6,7,8,9

for (int i : new Range(0,10,2)) {...} // i = 0,2,4,6,8

Range range = new Range(0,10,2);
range.toList(); // [0,2,4,6,8]

14
public int[] range(int start, int stop)
{
   int[] result = new int[stop-start];

   for(int i=0;i<stop-start;i++)
      result[i] = start+i;

   return result;
}

Пробачте будь-які синтаксичні чи стильові помилки; Я зазвичай програмую на C #.


враховуючи, що Вівіен Бароуз побив вас у відповідь, чому б не видалити своє, щоб уникнути дублінгу. Якщо ви дійсно не плануєте добре його м'якотіти, звичайно.
aaronasterling

9
Вони схожі; Я думаю, моє трохи читабельніше. Його використання "length" вводить в оману, і я не думаю, що його відповідає специфікація Python (він включає верхню межу, за якою network-theory.co.uk/docs/pytut/rangeFunction.html говорить, що не відбувається в Python ). Якщо ви думаєте, що хтось є дурнем, я вважаю, що ви маєте достатню репутацію, щоб вирішити це самостійно.
KeithS

10

Ви можете використовувати такий фрагмент коду, щоб отримати набір цілих чисел:

    Set<Integer> iset = IntStream.rangeClosed(1, 5).boxed().collect
            (Collectors.toSet());

7
public int[] range(int start, int length) {
    int[] range = new int[length - start + 1];
    for (int i = start; i <= length; i++) {
        range[i - start] = i;
    }
    return range;
}

(Довга відповідь, просто сказати "Ні")


Також дивіться, що "діапазон" в python 3 та переважний "xrange" в Python 2 повертають "живий" об'єкт, який не використовує пам'ять для кожного елемента, який він містить. Це було б ще більше втілити в Java.
jsbueno

3

Java 9 - IntStream::iterate

Оскільки Java 9 ви можете використовувати IntStream::iterateі ви навіть можете налаштувати крок. Наприклад, якщо ви хочете intмасив:

public static int[] getInRange(final int min, final int max, final int step) {
    return IntStream.iterate(min, i -> i < max, i -> i + step)
            .toArray();
}

або List:

public static List<Integer> getInRange(final int min, final int max, final int step) {
    return IntStream.iterate(min, i -> i < max, i -> i + step)
            .boxed()
            .collect(Collectors.toList());
}

А потім скористайтеся ним:

int[] range = getInRange(0, 10, 1);


2

Бібліотека "Функціональна Java" дозволяє програмувати таким чином в обмеженому ступені, вона має метод range (), створюючи екземпляр fj.data.Array.

Побачити:

Аналогічно бібліотека "Цілком ледачий" пропонує метод лінивого діапазону: http://code.google.com/p/totallylazy/


1

Якщо ви маєте на увазі використовувати його так, як би ви працювали в циклі Python, Java добре ув'язується з оператором for, що робить цю структуру непотрібною для цієї мети.


5
Ви також зазвичай не використовуєте його для циклу в python. Існує майже завжди більш чистий спосіб ітерації.
Daenyth

Ну, діапазон зазвичай використовується в циклі for. Але для петель часто застосовують без діапазону.
FogleBird


0

Я знаю, що це стара публікація, але якщо ви шукаєте рішення, яке повертає об'єктний потік і не хоче або не може використовувати додаткові залежності:

Stream.iterate(start, n -> n + 1).limit(stop);

старт - включно зупинка - ексклюзив

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.