2011-12-07 3 views
1

J'ai un problème où j'essaye de parcourir une arraylist qui stocke des objets de restaurant mais la boucle passe seulement par trois des cinq éléments.boucle ne pas itérateur à travers arraylist

J'ai créé une méthode d'essai pour illustrer:

public void testLoop() { 
     ArrayList<Eatery> test = new ArrayList<Eatery>(); 
     test = eateriesListDefault; 
     for(Eatery e : test) { 
      MyLog.e(TAG, "Name: " + e.getName()); 
     } 
     for (int i = 0; i < eateriesListDefault.size(); i++) { 
      MyLog.e(TAG, "Name " + test.get(i).getName()); 
      test.remove(i); 
     } 
     for(Eatery e : test) { 
      MyLog.e(TAG, "Name " + e.getName()); 
     } 
    } 

Ici essai aura 5 objets Eatery en elle. La première boucle imprime avec succès 5 des 5 noms. La deuxième boucle supprime seulement 3 des restaurants et donc la dernière boucle imprime deux noms.

J'ai essayé d'utiliser

for(Eatery e : eateriesListDefault) { 
      MyLog.e(TAG, "Name: " + e.getName()); 
      test.remove(e); 
} 

en place de la deuxième boucle, mais je reçois une erreur d'accès simultané.

Est-ce que quelqu'un sait ce que je fais mal?

+2

Tout d'abord, vous ne devriez pas utilisez une boucle 'foreach' lorsque vous essayez de retirer des valeurs de la collection. C'est la cause de votre erreur d'accès concurrent. Voir [cette page] (http://docs.oracle.com/javase/tutorial/collections/interfaces/collection.html). Pouvez-vous également expliquer pourquoi vous lancez un appel 'new ArrayList' uniquement pour créer une affectation sur la ligne suivante? – Grambot

+0

Est-il possible pour nous de voir à quoi ressembleront les restaurantsListDefault?Peut-être qu'au lieu de "pour (Eatery e: test)" comme la première boucle, vous devriez essayer et imiter votre 2ème boucle afin que vous puissiez comparer des pommes aux pommes. J'essaie juste d'exclure tout problème d'indexation. – dispake

Répondre

7

Vous appelez eateriesListDefault.size() à chaque itération de la boucle. En même temps, vous appelez test.remove(i) qui court-circuite le tableau d'une unité à chaque itération. Votre boucle fait essentiellement ceci:

  1. i = 0 size = 5 Continuez

  2. i = 1 size = 4 Continuez

  3. i = 2 size = 3 Continuez

  4. i = 3 size = 2 arrêter

Si vous êtes objectif était d'imprimer le premier élément du tableau, puis retirez-le, vous pourriez probablement y arriver par cette boucle:

while(!eateriesListDefault.isEmpty()) { 
    MyLog.e(TAG, "Name " + test.get(0).getName()); 
    test.remove(0); 
} 
+0

+1 belle illustration. Correction d'une faute de frappe. –

2

Votre deuxième boucle supprime des éléments du tableau alors que votre index de boucle continue d'augmenter. Au quatrième passage, votre index de boucle est 3, mais eateriesListDefault.size vaut 2, donc la boucle se termine.

Essayez ceci:

for (Iterator<Eatery> it = test.iterator(); it.hasNext();) { 
    MyLog.e(...) 
    it.remove(); 
} 

Le comportement d'un itérateur est non spécifiée si la liste est modifiée lors de l'itération de toute autre manière que par l'appel Iterator.remove(). Voir le Iterator.remove() documentation.

En outre, vous souhaiterez peut-être effectuer une copie de la liste par défaut. Votre "test =" instruction fait juste une nouvelle référence à la même liste.

test = new ArrayList<Eatery>(eateriesListDefault); 
+1

Dans une explication d'extension: si vous considérez comment la boucle fonctionne, vous obtenez plusieurs étapes: étape 1, taille de la liste = 5, supprimer un élément. étape 2, taille de la liste = 4 supprimer un élément. étape 3, taille de la boucle = 3, quitter. – Grambot

Questions connexes