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.