Java: ¿equivalente al rango de Python (int, int)?


99

¿Java tiene un equivalente al range(int, int)método de Python ?


¿Te refieres a un rango de Python 2.x que devuelve una lista, o un rango de Python 3.x que devuelve un iterador (equivalente al rango x 2.x)? El primero es relativamente simple de implementar como otros lo han hecho a continuación, pero la versión del iterador es un poco más complicada.
Dave Kirby


Para un rango de cualquier Comparables, vea esta respuesta
c0der

Para un rango con pasos, vea esto
Sławomir Lenart

Respuestas:


27

Guava también proporciona algo similar a Python range:

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

También puede implementar un iterador bastante simple para hacer el mismo tipo de cosas usando el AbstractIterator de 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
Ojalá hubiera visto esto antes de implementar mi propia gama genérica. Es agradable, pero es otro recordatorio de lo torpe que se puede comparar Java con lenguajes más funcionales.
z7sg Ѫ

14
Range#asSetParece que ha quedado obsoleto. Ahora necesita hacer esto:ContiguousSet.create(Range.closed(low, high), DiscreteDomain.integers())
Proyecto Chthonic

¿Qué biblioteca necesito importar para usar esto?
tgabb

Desde Java 8, IntStream y LongStream tienen métodos range y rangeClosed.
Jose Manuel Gomez Alvarez


16

Desde Guava 15.0, Range.asSet () ha quedado obsoleto y está programado para ser eliminado en la versión 16. Utilice lo siguiente en su lugar:

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

15

Estoy trabajando en una pequeña biblioteca de utilidades de Java llamada Jools , y contiene una clase Rangeque proporciona la funcionalidad que necesita (hay un JAR descargable).
Los constructores son o bien Range(int stop), Range(int start, int stop)o Range(int start, int stop, int step)(similar a un bucle for) y usted puede iterar a través de él, el cual utiliza la evaluación perezosa, o puede utilizar su toList()método para obtener explícitamente la lista de rangos.

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

Perdone cualquier error de sintaxis o estilo; Normalmente programo en C #.


Dado que Vivien Barousse se adelantó a una respuesta, ¿por qué no borra la suya para evitar duplicidades? A menos que realmente planees desarrollarlo bien, por supuesto.
aaronasterling

9
Son similares; Creo que el mío es un poco más legible. Su uso de "longitud" es engañoso, y no creo que cumpla con las especificaciones de Python (incluye el límite superior, que network-theory.co.uk/docs/pytut/rangeFunction.html dice que no ocurre en Python ). Si cree que uno es un engañado, creo que tiene la reputación suficiente para enfrentarse a él.
KeithS

10

Puede utilizar el siguiente fragmento de código para obtener un conjunto de rangos de enteros:

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

(Respuesta larga solo para decir "No")


Además, vea que "rango" en Python 3 y el "xrange" preferido en Python 2 devuelven un objeto "en vivo" que no usa memoria para cada elemento que contiene. Eso sería aún más grande de implementar en Java.
jsbueno

3

Java 9 - IntStream::iterate

Desde Java 9 puedes usar IntStream::iteratee incluso puedes personalizar el paso. Por ejemplo, si quieres una intmatriz:

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

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

Y luego úsalo:

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



1

Si tiene la intención de usarlo como lo haría en un bucle de Python, Java funciona bien con la instrucción for, lo que hace que esta estructura sea innecesaria para ese propósito.


5
Por lo general, tampoco lo usa para un bucle en Python. Casi siempre hay una forma más limpia de iterar.
Daenyth

Bueno, el rango se usa generalmente en un bucle for. Pero los bucles for se utilizan a menudo sin rango.
FogleBird

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

1
Sería útil si explicaras cómo este código resuelve el problema.
Robert Columbia

0

Sé que esta es una publicación antigua, pero si está buscando una solución que devuelva un flujo de objetos y no quiere o no puede usar ninguna dependencia adicional:

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

inicio - incluido parada - exclusivo

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.