Comment ajouter un élément dans la liste lors de l'itération en java?

Dites que j'ai une liste comme:

List<String> list = new ArrayList<>();
list.add("a");
list.add("h");
list.add("f");
list.add("s");

En parcourant cette liste, je veux ajouter un élément à la fin de la liste. Mais je ne veux pas parcourir les éléments nouvellement ajoutés, c'est-à-dire que je veux parcourir la taille initiale de la liste.

for (String s : list)
     /* Here I want to add new element if needed while iterating */

Quelqu'un Peut-il me suggérer comment puis-je faire cela?

24
demandé sur flyleaf 2012-06-24 16:13:48

5 réponses

Vous ne pouvez pas utiliser une instruction foreach pour cela. Le foreach utilise en interne un itérateur:

Les itérateurs renvoyés par l'itérateur et le listIterator de cette classe les méthodes sont fail-fast: si la liste est structurellement modifiée à tout temps après la création de l'itérateur, de quelque manière que ce soit, sauf à travers le les propres méthodes remove ou add de l'itérateur, l'itérateur lancera un ConcurrentModificationException.

(à partir de ArrayList javadoc)

Dans la déclaration foreach vous n'avez pas accès à la méthode add de l'itérateur et en tout cas ce n'est toujours pas le type d'ajout que vous voulez car il n'est pas ajouté à la fin. Vous devrez parcourir la liste manuellement:

int listSize = list.size();
for(int i = 0; i < listSize; ++i)
  list.add("whatever");

Notez que ceci n'est efficace que pour les listes qui permettent un accès aléatoire. Vous pouvez vérifier cette fonctionnalité en vérifiant si la liste implémente L'interface de marqueur RandomAccess. Un ArrayList a un accès aléatoire. Une liste liée ne le fait pas.

35
répondu yankee 2012-06-24 12:21:20

Il suffit d'itérer à l'ancienne, car vous avez besoin d'une gestion explicite de l'index:

List myList = ...
...
int length = myList.size();
for(int i = 0; i < length; i++) {
   String s = myList.get(i);
   // add items here, if you want to
}
8
répondu Fabian Barney 2012-06-24 12:18:41

Parcourir une copie de la liste et ajouter de nouveaux éléments à la liste d'origine.

for (String s : new ArrayList<String>(list))     
{
    list.add("u");
}

Voir Comment faire une copie de L'objet ArrayList qui est le type de liste?

6
répondu Rico Suter 2017-05-23 11:33:25

Vous pouvez itérer sur une copie (clone) de votre liste d'origine:

List<String> copy = new ArrayList<String>(list);
for (String s : copy) {
    // And if you have to add an element to the list, add it to the original one:
    list.add("some element");
}

Notez qu'il n'est même pas possible d'ajouter un nouvel élément à une liste en itérant dessus, car il en résultera un ConcurrentModificationException.

2
répondu buc 2012-06-24 12:25:47

Je le fais en ajoutant les éléments à une nouvelle liste tmp vide, puis en ajoutant la liste tmp à la liste d'origine en utilisant addAll(). Cela empêche de copier inutilement une grande liste de sources.

Imaginez ce qui se passe lorsque la liste originale de L'OP contient quelques millions d'éléments; pendant un moment, vous allez aspirer deux fois la mémoire.

En plus de conserver les ressources, cette technique nous empêche également de recourir au style 80s pour les boucles et d'utiliser ce qui est effectivement des index de tableau ce qui pourrait être peu attrayant dans certains cas.

0
répondu Tony Ennis 2012-06-24 12:46:25