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


99

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


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

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


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

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]

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 #.


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

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)


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

2

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



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.


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

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.