web-dev-qa-db-fra.com

Pour boucle - comme Python fonction de plage

Je me demandais si dans Java il y a une fonction comme la fonction python range).

range(4)

et il reviendrait

[0,1,2,3]

C'était un moyen facile de créer des boucles améliorées. Ce serait génial de le faire en Java car cela rendrait les boucles beaucoup plus faciles. Est-ce possible?

22
Kacper Lubisz

Java 8 a ajouté IntStream (similaire à Apache commons IntRange), vous n'avez donc plus besoin de lib externe.

IntStream.range(0, 3).forEachOrdered(n -> {
    //work on n here
});

forEach peut également être utilisé à la place de forEachOrdered si l'ordre n'est pas important.

37
zengr

Sans bibliothèque externe, vous pouvez effectuer les opérations suivantes. Il consommera beaucoup moins de mémoire pour les grandes plages que la réponse actuellement acceptée, car aucun tableau n'est créé.

Avoir une classe comme celle-ci:

class Range implements Iterable<Integer> {

    private int limit;

    public Range(int limit) {
        this.limit = limit;
    }

    @Override
    public Iterator<Integer> iterator() {
        final int max = limit;
        return new Iterator<Integer>() {

            private int current = 0;

            @Override
            public boolean hasNext() {
                return current < max;
            }

            @Override
            public Integer next() {
                if (hasNext()) {
                    return current++;   
                } else {
                    throw new NoSuchElementException("Range reached the end");
                }
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException("Can't remove values from a Range");
            }
        };
    }
}

et vous pouvez simplement l'utiliser comme ceci:

    for (int i : new Range(5)) {
        System.out.println(i);
    }

vous pouvez même le réutiliser:

    Range range5 = new Range(5);

    for (int i : range5) {
        System.out.println(i);
    }
    for (int i : range5) {
        System.out.println(i);
    }

Comme Henry Keiter l'a souligné dans le commentaire ci-dessous, nous pourrions ajouter la méthode suivante à la classe Range (ou n'importe où ailleurs):

public static Range range(int max) {
    return new Range(max);
}

puis dans les autres classes on peut

import static package.name.Range.range;

et appelez simplement

for (int i : range(5)) {
    System.out.println(i);
}
17
jlordo

Utilisez Apache Commons Lang :

new IntRange(0, 3).toArray();

Je ne recommanderais pas normalement l'introduction de bibliothèques externes pour quelque chose d'aussi simple, mais Apache Commons est si largement utilisé que vous l'avez probablement déjà dans votre projet!

Edit: je sais que ce n'est pas nécessairement aussi simple ou rapide qu'une boucle for, mais c'est un joli morceau de sucre syntaxique qui rend l'intention claire.

Edit: Voir @ zengr's answer using IntStream in Java 8.

11
Zutty

Um ... for (int i = 0; i < k; i++)? Vous n'avez pas à écrire amélioré pour les boucles toute la journée, vous savez, même si elles sont cool ...

Et juste pour les besoins de l'argumentation:

for (int i : range(k)) nombre de caractères: 22

for (int i = 0; i < k; i++) nombre de caractères: 27

Actualiser l'implémentation de range, c'est pseudo même.

10
zw324

Si vous voulez vraiment, vraiment obtenir un résultat équivalent en Java, vous devrez faire un peu plus de travail:

public int[] range(int start, int end, int step) {
    int n = (int) Math.ceil((end-start)/(double)step);
    int[] arange = new int[n];
    for (int i = 0; i < n; i++)
        arange[i] = i*step+start;
    return arange;
}

Maintenant, range(0, 4, 1) renverra la valeur attendue, tout comme Python: [0, 1, 2, 3]. Malheureusement, il n'y a pas de moyen plus simple en Java, c'est pas un langage très expressif, comme Python.

3
Óscar López

Ce n'est pas vraiment vrai. Mais vous créez une méthode statique et l'utilisez -

public static int[] range(int index){
    int[] arr = new int[index];
    for(int i=0;i<index;i++){
        arr[i]=i;
    }
    return arr;
}
1

Il n'y a pas Java équivalent à la fonction range, mais il y a boucle for améliorée :

for (String s : strings) {
    // Do stuff
}

Vous pouvez également lancer votre propre fonction range, si vous êtes vraiment attaché à la syntaxe, mais cela semble un peu idiot.

public static int[] range(int length) {
    int[] r = new int[length];
    for (int i = 0; i < length; i++) {
        r[i] = i;
    }
    return r;
}

// ...

String s;
for (int i : range(arrayOfStrings.length)) {
    s = arrayOfStrings[i];
    // Do stuff
}
0
Henry Keiter

Pour autant que je sache, il n'y a pas de fonction équivalente en Java. Mais vous pouvez l'écrire vous-même:

public static int[] range(int n) {
    int[] ans = new int[n];
    int i;
    for(i = 0; i < n; i++) {
        ans[i] = i;
    }
    return ans;
}
0
Barranka