Java: équivalent de la plage de Python (int, int)?

99

Java a-t-il un équivalent à la range(int, int)méthode de Python ?

Nick Heiner
la source
Voulez-vous dire une plage Python 2.x qui renvoie une liste, ou une plage Python 3.x qui renvoie un itérateur (équivalent à la plage x 2.x)? La première est relativement simple à implémenter comme d'autres l'ont fait ci-dessous, mais la version itérateur est un peu plus délicate.
Dave Kirby
Pour une gamme de tout Comparables, voir cette réponse
c0der
Pour une gamme avec pas à pas voir ceci
Sławomir Lenart

Réponses:

27

Guava fournit également quelque chose de similaire à celui de Python range:

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

Vous pouvez également implémenter un itérateur assez simple pour faire le même genre de chose en utilisant 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;
  }
};
Simon Steele
la source
6
J'aurais aimé voir cela avant de mettre en place ma propre gamme générique. C'est bien mais c'est encore un autre rappel de la façon dont Java maladroit peut être comparé à des langages plus fonctionnels.
z7sg Ѫ
14
Range#asSetCela semble être devenu obsolète. Vous devez maintenant faire ceci:ContiguousSet.create(Range.closed(low, high), DiscreteDomain.integers())
Chthonic Project
quelle bibliothèque dois-je importer pour l'utiliser?
tgabb
À partir de Java 8, IntStream et LongStream ont des méthodes range et rangeClosed.
Jose Manuel Gomez Alvarez
225

Ancienne question, nouvelle réponse (pour Java 8)

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

ou avec des références de méthode:

IntStream.range(0, 10).forEach(System.out::println);
jhodges
la source
1
Quel paquet? comment puis-je l'importer?
Justin Thomas
6
@Justin C'est la fonctionnalité du langage Java 8.
Tzafrir
16

Depuis Guava 15.0, Range.asSet () est obsolète et devrait être supprimé dans la version 16. Utilisez plutôt ce qui suit:

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

Je travaille sur une petite bibliothèque d'utils Java appelée Jools , et elle contient une classe Rangequi fournit les fonctionnalités dont vous avez besoin (il y a un JAR téléchargeable).
Les constructeurs sont soit Range(int stop), Range(int start, int stop)ou Range(int start, int stop, int step)(similaire à une boucle) et vous pouvez itérer à travers elle, qui a utilisé l' évaluation paresseuse, ou vous pouvez utiliser la toList()méthode pour obtenir explicitement la liste de gamme.

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

Pardonnez toute erreur de syntaxe ou de style; Je programme normalement en C #.

KeithS
la source
étant donné que Vivien Barousse vous a battu à une réponse, pourquoi ne supprimez-vous pas la vôtre pour éviter toute duperie. À moins que vous ne prévoyiez vraiment de l'étoffer bien, bien sûr.
aaronasterling
9
Ils sont similaires; Je pense que le mien est un peu plus lisible. Son utilisation de la "longueur" est trompeuse, et je ne pense pas que la sienne réponde à la spécification Python (il inclut la borne supérieure, ce que network-theory.co.uk/docs/pytut/rangeFunction.html dit ne se produit pas en Python ). Si vous pensez que l'on est dupe, je pense que vous avez une réputation suffisante pour y faire face vous-même.
KeithS
10

Vous pouvez utiliser l'extrait de code suivant pour obtenir un ensemble de plages d'entiers:

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

(Longue réponse juste pour dire "non")

Vivien Barousse
la source
Aussi, voyez que "range" en python 3 et le "xrange" préféré en Python 2 renvoient un objet "live" qui n'utilise pas de mémoire pour chaque élément qu'il contient. Ce serait encore plus gros à implémenter en Java.
jsbueno
3

Java 9 - IntStream::iterate

Depuis Java 9, vous pouvez utiliser IntStream::iterateet vous pouvez même personnaliser l'étape. Par exemple, si vous voulez un inttableau:

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

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

Et puis utilisez-le:

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

La classe Range de Groovy peut être utilisée à partir de Java, bien qu'elle ne soit certainement pas aussi groovy.

John
la source
1

Si vous avez l'intention de l'utiliser comme vous le feriez dans une boucle Python, Java boucle bien avec l'instruction for, ce qui rend cette structure inutile à cette fin.

Nikki9696
la source
5
Vous ne l'utilisez généralement pas non plus pour une boucle en python. Il y a presque toujours une manière plus propre d'itérer.
Daenyth
Eh bien, la plage est généralement utilisée dans une boucle for. Mais les boucles for sont souvent utilisées sans portée.
FogleBird
1
IntStream.range(0, 10).boxed().collect(Collectors.toUnmodifiableList());
Pierre
la source
1
Cela vous aiderait si vous expliquiez comment ce code résout le problème.
Robert Columbia
0

Je sais que c'est un ancien article, mais si vous recherchez une solution qui renvoie un flux d'objets et que vous ne voulez ou ne pouvez pas utiliser de dépendances supplémentaires:

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

start - stop inclus - exclusif

HDubz
la source