tejas
tejas

Reputation: 2445

Concurrent modification exception for list

Can anybody tell me where I am going wrong here?

  File promoCountFile = new File(RaconTours.PATH + "promocodeCount.txt");
            if (promoPlistPath.exists()) {
                try {
                    ObjectInputStream inStream = new ObjectInputStream(new FileInputStream(promoPlistPath));
                    ObjectInputStream promoStream = new ObjectInputStream(new FileInputStream(promoCountFile));
                    promoobj = (ArrayList<HashMap<String, Object>>) promoStream.readObject();
                    obj = (ArrayList<HashMap<String, Object>>) inStream.readObject();
                    for (HashMap<String, Object> tmpObj : obj) {
                        promoTourname = (String) tmpObj.get("promoTour");
                        promocodeID = (String) tmpObj.get("promocode");
                        if (promoTourname.equals(currentTour.getObjtourName())) {
                            //if the condition is met, remove the entry from the file
                            for (HashMap<String, Object> promoTemp : promoobj) {
                                promoTourCount =  (Integer) promoTemp.get("promocodeTourCount");
                            }

                            obj.remove(tmpObj);
                            --promoTourCount; 

                            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(promoPlistPath)); 
                            out.writeObject(obj);
                            out.close();

                            ObjectOutputStream promoout = new ObjectOutputStream(new FileOutputStream(promoCountFile)); 
                            HashMap<String, Object> promoCountDict = new HashMap<String, Object>();
                            promoobj.remove(0);
                            promoCountDict.put("promocodeTourCount",promoTourCount);
                            promoobj.add(promoCountDict);
                            promoout.writeObject(promoobj);
                            promoout.close();


                        }
                    }


                    if (obj.size() == 0 || promoTourCount == 0) {
                        promoPlistPath.delete();
                        promoCountFile.delete();
                    }
                } catch (Exception e) { 
                    e.printStackTrace();
                }

            }

Here it is giving me concurrent modification exception while the for loop iterates for the 2nd time or after that.

I am trying to update the value of promoTourCount in file each time as the loop iterates. But I am failing to do it. Because to avoid adding up multiple objects I am removing the object present at position 0 and adding the new one to that position( promoobj.remove(0);)

Plz help me

Upvotes: 0

Views: 858

Answers (1)

Boris Strandjev
Boris Strandjev

Reputation: 46943

You are modifying the collection you are iterating on. This will trigger an error. You iterate over obj here:

for (HashMap<String, Object> tmpObj : obj) {

But remove from it here:

obj.remove(tmpObj);

I recommend you to store the items to remove in another collection and remove them from the map only when you finish the for loop.

Edit: << Adding example code >>

List<Integer> toRemove = new LinkedList<Integer>();
for (int i = 0; i < obj.size(); i++) {
    HashMap<String, Object> tmpObj = obj.get(i);

    if (/* something */) {
        /* ... */
        /* obj.remove(tmpObj);  replaced with*/
        toRemove.add(0, i); // notice that I add bigger indices first
    }
}
// Here we make the removal from bigger indices to smaller ones
// Notice that we iterate and remove from different collections.
for (Integer indexToDelete : toRemove) {
    obj.remove(indexToDelete);
}

This is the basic idea when you want to remove elements. However you need to output obj as modified immediately in the for loop. Then probably a bit of hacks with the indices will do better job for you:

for (int i = 0; i < obj.size(); i++) {
    HashMap<String, Object> tmpObj = obj.get(i);

    if (/* something */) {
        /* ... */
        /* obj.remove(tmpObj);  replaced with*/
        obj.remove(i); // We erase the element but this time we do not use enhanced for loop which is ok.
        i--; // we decrease the index because th enumber of elements decreased. Index hack. Ugly.
        System.out.println(obj); // modified obj :)
    }
}

Upvotes: 2

Related Questions