Java: Entspricht dem Bereich von Python (int, int)?

99

Hat Java eine Entsprechung zu Pythons range(int, int)Methode?

Nick Heiner
quelle
Meinen Sie einen Python 2.x-Bereich, der eine Liste zurückgibt, oder einen Python 3.x-Bereich, der einen Iterator zurückgibt (entspricht dem 2.x xrange)? Ersteres ist relativ einfach zu implementieren, wie andere unten beschrieben haben, aber die Iteratorversion ist etwas kniffliger.
Dave Kirby
Für eine Reihe von Comparables siehe diese Antwort
c0der
Für eine Reichweite mit Schritt siehe diese
Sławomir Lenart

Antworten:

27

Guave bietet auch etwas Ähnliches wie Python range:

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

Sie können auch einen ziemlich einfachen Iterator implementieren, um dasselbe mit Guavas AbstractIterator zu tun:

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

  @Override protected Integer computeNext() {
    if (isBeyondEnd(next)) {
      return endOfData();
    }
    Integer result = next;
    next = next + getStep();
    return result;
  }
};
Simon Steele
quelle
6
Ich wünschte, ich hätte dies gesehen, bevor ich mein eigenes generisches Sortiment implementiert habe. Es ist schön, aber noch eine weitere Erinnerung daran, wie klobig Java mit funktionaleren Sprachen verglichen werden kann.
z7sg Ѫ
14
Range#asSetes scheint veraltet zu sein. Sie müssen dies jetzt tun:ContiguousSet.create(Range.closed(low, high), DiscreteDomain.integers())
Chthonic Project
Welche Bibliothek muss ich importieren, um dies zu verwenden?
Tgabb
Ab Java 8 haben IntStream und LongStream die Methoden range und rangeClosed.
Jose Manuel Gomez Alvarez
225

Alte Frage, neue Antwort (für Java 8)

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

oder mit Methodenreferenzen:

IntStream.range(0, 10).forEach(System.out::println);
jhodges
quelle
1
Welches Paket? Wie importiere ich es?
Justin Thomas
6
@ Justin Das ist Java 8 Sprachfunktion.
Tzafrir
16

Seit Guava 15.0 ist Range.asSet () veraltet und soll in Version 16 entfernt werden. Verwenden Sie stattdessen Folgendes:

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

Ich arbeite an einer kleinen Java-Utils-Bibliothek namens Jools , die eine Klasse enthält, Rangedie die von Ihnen benötigte Funktionalität bietet (es gibt eine herunterladbare JAR).
Konstruktoren sind entweder Range(int stop), Range(int start, int stop)oder Range(int start, int stop, int step)(ähnlich einer for-Schleife), und Sie können sie entweder durchlaufen, wobei eine verzögerte Auswertung verwendet wurde, oder Sie können ihre toList()Methode verwenden, um die Bereichsliste explizit abzurufen.

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]
Amir Rachum
quelle
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;
}

Verzeihen Sie Syntax- oder Stilfehler. Normalerweise programmiere ich in C #.

KeithS
quelle
Angesichts der Tatsache, dass Vivien Barousse Sie zu einer Antwort geschlagen hat, warum löschen Sie Ihre nicht, um Dup zu vermeiden? Es sei denn, Sie planen wirklich, es natürlich schön zu fleischen.
Aaronasterling
9
Sie sind ähnlich; Ich denke, meine ist etwas besser lesbar. Seine Verwendung von "Länge" ist irreführend, und ich glaube nicht, dass er die Python-Spezifikation erfüllt (er enthält die Obergrenze, die laut network-theory.co.uk/docs/pytut/rangeFunction.html in Python nicht vorkommt ). Wenn Sie denken, dass jemand ein Betrüger ist, glaube ich, dass Sie einen ausreichenden Ruf haben, um sich selbst darum zu kümmern.
KeithS
10

Sie können das folgende Codefragment verwenden, um einen Bereichssatz von Ganzzahlen abzurufen:

    Set<Integer> iset = IntStream.rangeClosed(1, 5).boxed().collect
            (Collectors.toSet());
julianisch
quelle
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;
}

(Lange Antwort, nur um "Nein" zu sagen)

Vivien Barousse
quelle
Beachten Sie auch, dass "range" in Python 3 und der bevorzugte "xrange" in Python 2 ein "live" -Objekt zurückgeben, das nicht für jedes darin enthaltene Element Speicher belegt. Das wäre noch größer in Java zu implementieren.
Jsbueno
3

Java 9 - IntStream::iterate

Seit Java 9 können IntStream::iterateSie den Schritt verwenden und sogar anpassen. Zum Beispiel, wenn Sie intArray wollen :

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

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

Und dann benutze es:

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

Groovys raffinierte Range-Klasse kann von Java aus verwendet werden, obwohl sie sicherlich nicht so groovig ist.

John
quelle
1

Wenn Sie es wie in einer Python-Schleife verwenden möchten, führt Java eine gute Schleife mit der for-Anweisung durch, wodurch diese Struktur für diesen Zweck unnötig wird.

Nikki9696
quelle
5
Normalerweise verwenden Sie es auch nicht für eine Schleife in Python. Es gibt fast immer eine sauberere Art zu iterieren.
Daenyth
Nun, Bereich wird normalerweise in einer for-Schleife verwendet. Aber für Schleifen werden oft ohne Reichweite verwendet.
FogleBird
1
IntStream.range(0, 10).boxed().collect(Collectors.toUnmodifiableList());
Pierre
quelle
1
Es wäre hilfreich, wenn Sie erklären würden, wie dieser Code das Problem löst.
Robert Columbia
0

Ich weiß, dass dies ein alter Beitrag ist, aber wenn Sie nach einer Lösung suchen, die einen Objektstrom zurückgibt und keine zusätzlichen Abhängigkeiten verwenden möchte oder kann:

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

Start - inklusive Stopp - exklusiv

HDubz
quelle