Java: equivalente dell'intervallo di Python (int, int)?


99

Java ha un equivalente al range(int, int)metodo di Python ?


Intendi un intervallo Python 2.x che restituisce un elenco o un intervallo Python 3.x che restituisce un iteratore (equivalente a 2.x xrange)? Il primo è relativamente semplice da implementare come altri hanno fatto di seguito, ma la versione iteratore è un po 'più complicata.
Dave Kirby


Per una serie di eventuali Comparables vedere questa risposta
c0der

Per una serie di passi vedere questo
Sławomir Lenart,

Risposte:


27

Guava fornisce anche qualcosa di simile a Python range:

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

Puoi anche implementare un iteratore abbastanza semplice per fare lo stesso genere di cose usando AbstractIterator di 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
Vorrei averlo visto prima di implementare la mia gamma generica. È bello ma è ancora un altro promemoria di quanto Java possa essere paragonato a linguaggi più funzionali.
z7sg Ѫ

14
Range#asSetsembra essere diventato obsoleto. Ora devi fare questo:ContiguousSet.create(Range.closed(low, high), DiscreteDomain.integers())
Chthonic Project

quale libreria devo importare per utilizzarla?
tgabb

Da Java 8, IntStream e LongStream hanno metodi range e rangeClosed.
Jose Manuel Gomez Alvarez


16

A partire da Guava 15.0, Range.asSet () è stato deprecato e dovrebbe essere rimosso nella versione 16. Utilizzare invece quanto segue:

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

15

Sto lavorando a una piccola libreria di utilità Java chiamata Jools , e contiene una classe Rangeche fornisce le funzionalità necessarie (c'è un JAR scaricabile).
Costruttori sono o Range(int stop), Range(int start, int stop)o Range(int start, int stop, int step)(simile ad un ciclo for) e potete iterare attraverso di essa, che ha usato la valutazione pigra, oppure si può usare il suo toList()metodo per ottenere l'elenco in modo esplicito gamma.

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

Perdona eventuali errori di sintassi o di stile; Normalmente programma in C #.


dato che Vivien Barousse ti ha battuto a una risposta, perché non elimini la tua per evitare qualsiasi duplicazione. A meno che tu non abbia davvero intenzione di rimpolparlo bene, naturalmente.
aaronasterling

9
Sono simili; Penso che il mio sia un po 'più leggibile. Il suo uso di "length" è fuorviante e non credo che soddisfi le specifiche di Python (include il limite superiore, che network-theory.co.uk/docs/pytut/rangeFunction.html dice non accade in Python ). Se pensi che sia uno stupido, credo di avere una reputazione sufficiente per affrontarlo da solo.
KeithS

10

Puoi utilizzare il seguente frammento di codice per ottenere un set di intervalli di numeri interi:

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

(Risposta lunga solo per dire "No")


Inoltre, guarda che "range" in python 3 e il preferito "xrange" in Python 2 restituiscono un oggetto "live" che non utilizza memoria per ogni elemento che contiene. Sarebbe ancora più grande da implementare in Java.
jsbueno

3

Java 9 - IntStream::iterate

Da Java 9 puoi usare IntStream::iteratee puoi persino personalizzare il passaggio. Ad esempio, se vuoi un intarray:

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

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

E poi usalo:

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



1

Se intendi usarlo come faresti in un ciclo Python, Java funziona bene con l'istruzione for, che rende questa struttura non necessaria a tale scopo.


5
Di solito non lo usi nemmeno per un ciclo in Python. C'è quasi sempre un modo più pulito per iterare.
Daenyth

Bene, l'intervallo viene solitamente utilizzato in un ciclo for. Ma i loop sono spesso usati senza range.
FogleBird

1
IntStream.range(0, 10).boxed().collect(Collectors.toUnmodifiableList());

1
Sarebbe utile se spiegassi come questo codice risolve il problema.
Robert Columbia

0

So che questo è un vecchio post, ma se stai cercando una soluzione che restituisca un flusso di oggetti e non vuoi o non puoi usare dipendenze aggiuntive:

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

start - inclusive stop - esclusivo

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.