2
votes

Initialiser ArrayList avec une plage de valeurs entières évitant les boucles

Je voudrais initialiser une ArrayList avec une plage de valeurs entières. C'est ce que je veux éviter:

IntStream.rangeClosed(0, instance.getNumVertices()-1);

J'ai trouvé la fonction rangeClosed pour IntStream:

ArrayList<Integer> numbers = new ArrayList<>();
for(int i = 0; i < x; i++){
    numbers.add(i);
}

Mais je pense que la conversion en ArrayList a gagné ça vaut pas le coup.

Je recherche l'efficacité ...


2 commentaires

Qu'entendez-vous exactement par «efficacité»? Toute méthode, que vous utilisiez explicitement une boucle vous-même ou non, est susceptible de l'implémenter à l'aide d'une boucle. Il n'y a pas de moyen magique d'initialiser un tableau sans une sorte de boucle. Il vaut mieux écrire du code clair et facile à comprendre que d'utiliser des astuces que vous pensez plus efficaces, sans avoir preuve que cela améliore en quelque sorte votre programme.


Je suis d'accord, mais il peut être possible de ne pas générer les éléments du tableau tant qu'ils ne sont pas nécessaires, bien qu'en interne le programme soit conscient des éléments qu'il contient.


3 Réponses :


5
votes

La ArrayList est soutenue par un tableau. Si vous voulez le remplir avec des valeurs croissantes, vous n'obtiendrez pas plus rapidement que simplement itérer sur ces valeurs et les ajouter à la liste.

La seule chose que je changerais dans votre exemple est d'initialiser le tableau avec le déjà taille connue, de sorte qu'il ne passe pas de temps et de mémoire sur l'extension du tableau sous-jacent:

ArrayList<Integer> numbers = new ArrayList<>(x);
for(int i = 0; i < x; i++){
    numbers.add(i);
}


0 commentaires

1
votes

Si vous voulez avoir un objet qui ressemble à une List qui contient des nombres de 0 à N sans réellement stocker ces nombres, alors vous pouvez implémenter votre propre liste, par exemple comme ceci:

List<Integer> numbers = new RangeList(10);

Vous pouvez en créer une instance comme ceci:

import java.util.AbstractList;

public class RangeList extends AbstractList<Integer> {
    private final int size;

    public RangeList(int size) {
        this.size = size;
    }

    @Override
    public Integer get(int index) {
        return index;
    }

    @Override
    public int size() {
        return size;
    }
}

Il se comporte comme un ArrayList contenant les valeurs 0 à 9, mais vous ne pouvez pas modifier la liste (l'ajout, la suppression, la modification d'entrées entraînera une UnsupportedOperationException).


0 commentaires

0
votes

Quelle que soit la façon dont vous décidez de remplir la ArrayList, vous devrez boucler ou utiliser chaque valeur stockée dans ArrayList une par une. Il n'y a pas de moyen plus rapide que d'itérer chaque valeur et de l'ajouter à ArrayList, seulement des moyens qui la rendent plus propre.

Créer une fonction qui le fait ou une extension de l'objet ArrayList sont deux façons de le faire.

private ArrayList<Integer> fillRange(int min, int max){
    ArrayList<Integer> a_lst = new ArrayList<>();
    for(int i = min; i < max; i++){
        a_lst.add(i);
    }
    return a_lst;
}


0 commentaires