2010-05-11 11 views
1

Ceci est mon code:[Java] file d'attente dans la boucle while, ne peut pas modifier la valeur?

Iterator it = queue.iterator(); 

while(it.hasNext()){ 
    random = randNumber(1,2); 
     if(random == 1){ 
      queue.poll(); 
     } else { 
      queue.add("new"); 
      queue.poll(); 
     } 
} 

Il me donne:

Exception in thread "test" java.util.ConcurrentModificationException 
    at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:761) 
    at java.util.LinkedList$ListItr.next(LinkedList.java:696) 

Modifier Skeet @ Jon:

Ce que je veux faire est:

  • J'ai liste de file d'attente, laissez-dire la taille est de 10, permet de dire: a, b, c, d ... j
  • Générer un nombre compris entre 1 et 2. Si 1, tirez (retirer l'élément supérieur) d'autre si 2 ajouter nouvel élément
  • Je vais arrêter la boucle jusqu'à ce que j'ajouté 3 nouveaux éléments
+0

q est-il identique à la file d'attente? – Shaded

+0

@shaded: Oui, je viens d'éditer ma question pour éviter la confusion –

Répondre

7

En général, vous pouvez Ne modifiez pas les collections pendant que vous itérez sur elles. Une alternative consiste à construire une liste séparée des « changements » que vous souhaitez appliquer, puis les appliquer une fois que vous avez terminé itérer.

Par ailleurs, certaines collections suportent ce, comme ConcurrentLinkedQueue - mais la plupart offrent aucune garantie quant à savoir si l'itérateur voir les changements effectués pendant que vous êtes itérer. (Je soupçonne que ce principalement parce qu'ils sont aussi thread-safe, mais j'ai rarement vu des garanties documentées sur ce qui se passera si vous modifiez la collection dans le fil de itérer.)

EDIT: Je ne suis pas sûr qu'un itérateur est la bonne approche ici. Au lieu de cela, vous pouvez utiliser:

while (!queue.isEmpty()) 
{ 
    // Put logic in here - add, poll etc 
} 

Une chose à noter est que votre code ne se déplace pas affiché le fait l'itérateur avant à tout moment - il appelle jamais it.next(). C'est une suggestion forte que soit vous ne l'utilisez l'itérateur complètement, ou vous n'avez pas besoin du tout.

+0

Hmm .. je ne peux pas le faire pendant itérer ... :( Je ne vous obtenez pas de façon alternative.Peut donner quelques exemples? –

+0

@javaLearner: Cela dépend vraiment de quoi vous voulez atteindre - quel est votre but réel ici? Avez-vous besoin de votre itérateur pour "voir" les éléments supplémentaires que vous ajoutez –

+0

Y at-il un moyen de lancer l'exception ConcurrentModificationException? –

0

Est-ce vraiment copier-collé votre code?

Ce que je peux penser est que vous confirmé que q et queue sont des références à la même file d'attente objet.
Vous ne pouvez donc modifier aucun type de liste, de file d'attente ou de pile lors de l'itération. Pour éviter l'itération, vous pouvez essayer une boucle for(int i = 0; ..... ; i++). Mais ce n'est pas une bonne idée. Parce que vous changez de taille lorsque vous utilisez la taille pour vérifier si vous êtes à la fin de la boucle.


Je lis votre edit:

for (int i = 0; i < 3;) 
{ 
    boolean b = Math.random() < 0.5d; 
    if (b) 
    { 
     queue.poll(); 
    } else { 
     queue.add("new"); // or put(), I don't know exectly 
     i++; 
    } 
} 
+0

Oui, c'est mon code très original. Je copie mon code, puis je le modifie (inclure le nom de la variable), mais le flux est le même. –

+0

@Martin: J'ai essayé d'utiliser la boucle "for", cela n'aide pas = ( –

+0

je veux dire, je copie coller mon code et modifie le nom de la variable.Je suis 100% confirmer que les "q" et "queue" sont des références à le même objet file d'attente. –

0

Si 'file' est une liste, vous pouvez utiliser ListIterator

extrait:

Itérateur pour les listes qui permet au programmeur de parcourir la liste dans les deux sens, modifier la liste pendant l'itération, et obtenir la position actuelle de l'itérateur dans t Il liste.

0

Vous devez utiliser ListIterator. Il a des méthodes .remove() et .set() qui vous permettront de modifier la collection sous-jacente sans arroser l'état de l'itérateur. En général, modifier la collection de toute autre manière va ralentir l'état de l'itérateur. Sois content qu'il ait jeté une exception et qu'il n'ait pas fait quelque chose de plus insidieux.