Page 1 of 3 123 LastLast
Results 1 to 20 of 51
  1. #1
    Newbie666 is offline Member
    Join Date
    Jan 2010
    Posts
    46
    Rep Power
    0

    Default Getting around a ConcurrentModificationException

    Hey,
    I'm getting a concurrentModificationException, I looked this up and understand why this is, because I am changing the List while iterating over the List.
    I'm wondering how I can get around this, I assume I would have to use a normal for loop, with myList.size() as the condition.

    However I'm having trouble trying to call the element in question. eg.
    myList[i] or myList(i) don't seem to work. I have only used the iterator for loop for lists before.
    Is there another way?

  2. #2
    r035198x is offline Senior Member
    Join Date
    Aug 2009
    Posts
    2,388
    Rep Power
    8

    Default

    Use an Iterator and modify the List via the Iterator.

  3. #3
    Newbie666 is offline Member
    Join Date
    Jan 2010
    Posts
    46
    Rep Power
    0

    Default

    oh so I am only getting the exception because I am calling the list as?
    Java Code:
    for ( MyClass list : myList )
    does using iterator get around this?

    Java Code:
    import java.util.Iterator;
    ...
    for (Iterator it = myList.iterator(); it.hasNext();) 
    {
        System.out.println(((String)it.next()));
        // modify the list here...
    }

  4. #4
    masijade is offline Senior Member
    Join Date
    Jun 2008
    Posts
    2,571
    Rep Power
    9

    Default

    Don't "modify the list here", use it.remove().
    Edit: although that depends, partly, on what "modify list here" means.

  5. #5
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    Quote Originally Posted by Newbie666 View Post
    oh so I am only getting the exception because I am calling the list as?
    Java Code:
    for ( MyClass list : myList )
    You're getting the exception because you're trying to modify (usually delete) the list from the foreach loop.

    does using iterator get around this?

    Java Code:
    import java.util.Iterator;
    ...
    for (Iterator it = myList.iterator(); it.hasNext();) 
    {
        System.out.println(((String)it.next()));
        // modify the list here...
    }
    try it and see?

    Though if possible, try to use a generic Iterator<T>.

  6. #6
    Newbie666 is offline Member
    Join Date
    Jan 2010
    Posts
    46
    Rep Power
    0

    Default

    try it and see?
    I'm trying and failing... I can't call methods from the object this way..

    Java Code:
    for (Iterator it = myList.iterator(); it.hasNext();) 
    {
        it.convertElement();  // can only use Iterator methods, hasNext(), remove(), next()
    }
    How do I use the objects' methods' in the List?

  7. #7
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

  8. #8
    Cbani is offline Member
    Join Date
    Jan 2010
    Posts
    90
    Rep Power
    0

    Default

    its very simple..change the list to a vector...everything works fine....
    or else if you dont want to do so then do as follows while constructing your list.

    List arl = Collections.synchronizedList(new ArrayList());

  9. #9
    Newbie666 is offline Member
    Join Date
    Jan 2010
    Posts
    46
    Rep Power
    0

    Default

    Quote Originally Posted by Fubarable View Post
    I'd try calling the "next()" method once in the loop to get the object from the list.
    I'm still uncertain how to use the objects methods'
    both these attempts were unsuccessful

    Java Code:
    for (Iterator it = myList.iterator(); it.hasNext();) 
    {
        it.next();
        it.convertElement();
    }
    and

    Java Code:
    for (Iterator it = myList.iterator(); it.hasNext(); it.next()) 
    {
        it.convertElement();
    }
    and

    Java Code:
    for (Iterator it = myList.iterator(); it.hasNext(); ) 
    {
        it.next().convertElement();
    }
    Last edited by Newbie666; 01-22-2010 at 03:34 PM.

  10. #10
    Cbani is offline Member
    Join Date
    Jan 2010
    Posts
    90
    Rep Power
    0

    Default

    hey newbie66,
    just try with the above approach and please do post what is the output..

  11. #11
    Newbie666 is offline Member
    Join Date
    Jan 2010
    Posts
    46
    Rep Power
    0

    Default

    which approach? I posted 3, all failed according to eclipse:

    the last suggests the method is undefined for the type Object

  12. #12
    Newbie666 is offline Member
    Join Date
    Jan 2010
    Posts
    46
    Rep Power
    0

    Default

    private List<MyClass> myList = new synchronizedList(new ArrayList(1000));
    &
    private List<MyClass> myList = new Collections.synchronizedList(new ArrayList(1000));

    both have an error: Collections.synchronizedList cannot be resolved to a type.

    private List<MyClass> myList = Collections.synchronizedList(new ArrayList(1000));

    warning: Type saftey warnings.
    suggested add @SuppressWarnings 'unchecked'

  13. #13
    Cbani is offline Member
    Join Date
    Jan 2010
    Posts
    90
    Rep Power
    0

    Default

    Cbani
    Member

    Join Date: Jan 2010
    Posts: 34
    Rep Power: 0



    its very simple..change the list to a vector...everything works fine....
    or else if you dont want to do so then do as follows while constructing your list.

    List arl = Collections.synchronizedList(new ArrayList());
    I am talking about the above one...

  14. #14
    Newbie666 is offline Member
    Join Date
    Jan 2010
    Posts
    46
    Rep Power
    0

    Default

    Quote Originally Posted by Cbani View Post
    I am talking about the above one...
    ConcurrentModificationException()

  15. #15
    Cbani is offline Member
    Join Date
    Jan 2010
    Posts
    90
    Rep Power
    0

    Default

    private List<MyClass> myList = new synchronizedList(new ArrayList(1000));
    &
    private List<MyClass> myList = new Collections.synchronizedList(new ArrayList(1000));


    this would definitely give you an compilation error as you are using generics.
    You have to do in this way as below
    List<MyClass> arl = Collections.synchronizedList(new ArrayList<MyClass>(1000));

    and you can ignore incase you get warning: Type saftey warnings.
    suggested add @SuppressWarnings 'unchecked'
    Last edited by Cbani; 01-22-2010 at 04:07 PM.

  16. #16
    Cbani is offline Member
    Join Date
    Jan 2010
    Posts
    90
    Rep Power
    0

    Default

    Hey Newbie666 ,

    any luck after trying the latest post by CBANI

  17. #17
    Newbie666 is offline Member
    Join Date
    Jan 2010
    Posts
    46
    Rep Power
    0

    Default

    no because the API still says I must use:

    Java Code:
    synchronized(list) {
          Iterator i = list.iterator(); // Must be in synchronized block
          while (i.hasNext())
              foo(i.next());
      }
    So I have the same problems as before, also I don't understand what:
    foo (Object) is supposed to represent.
    obviously not a method, .... perhaps the list? myList(i.next()); ??

  18. #18
    Cbani is offline Member
    Join Date
    Jan 2010
    Posts
    90
    Rep Power
    0

    Default

    if you are using this
    no because the API still says I must use:

    Code:
    synchronized(list) {
    Iterator i = list.iterator(); // Must be in synchronized block
    while (i.hasNext())
    foo(i.next());
    }
    then you have to pass the class type inside synchronized(list)..
    which would look like synchronized(List)

  19. #19
    Newbie666 is offline Member
    Join Date
    Jan 2010
    Posts
    46
    Rep Power
    0

    Default

    I know that's what I did, I'm simply posting sample code.

    Could you or somebody please post some sample code as to how you would go about modifying a List object using a set method please?

    It's not like I'm homework dumping... I'm pretty sure my question is pretty specific.

    What I am trying to do is traverse the list, if some objects have a specific boolean variable, then I am adding more to the list depending on how many elements/objects have that boolean set to true, also I am changing another boolean using a set method.

  20. #20
    Newbie666 is offline Member
    Join Date
    Jan 2010
    Posts
    46
    Rep Power
    0

    Default

    Here's my code:

    Java Code:
    package bunny;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Scanner;
    
    @SuppressWarnings("unchecked")
    public class FieldOfBunnies
    {
    	/*
    	 * class will create random 5 bunnies each turn.
    	 * class will process existing bunnies and make subsequent bunnies
    	 * based on existing sexes and ages.
    	 */
    	private static final String BOY_NAMES = "names/boynames.txt";
    	private static final String GIRL_NAMES = "names/girlnames.txt";
    	private List<String> boyNames = new ArrayList<String>(1000);
    	private List<String> girlNames = new ArrayList<String>(1000);
    	private List<Bunny> bunnyList = Collections.synchronizedList(new ArrayList(1000));
    	
    	public void turn()
    	{
    		int bunniesPerTurn=5;
    		for (int i=0;i<bunniesPerTurn;i++)
    		{
    			generateBunny();
    		}
    		calculateOffspring();
    		for (Bunny bunny : bunnyList)
    			bunny.setAge(bunny.getAge()+1);
    		Collections.shuffle(bunnyList);
    	}
    	
    	public void calculateOffspring()
    	{
    		synchronized(bunnyList) {
    		      Iterator i = bunnyList.iterator(); // Must be in synchronized block
    		      while (i.hasNext())
    		      {
    		    	  
    		      }
    		  }
    
    		for (Bunny bunny : bunnyList)
    		{
    			// if female, 2yo or greater, and not mutant
    			if ((bunny.getSex()) && (bunny.getAge()>=2) && (! bunny.getRadioactive()))
    				generateBunny();
    			
    			if (bunny.getRadioactive())
    			{
    				convertBunny();
    				if (bunny.getAge()>=50)
    				{
    					// bunny dies
    					bunnyList.remove(bunny);
    				}
    			}
    			else if (bunny.getAge()==10)
    			{
    				// bunny dies
    				bunnyList.remove(bunny);
    			}
    		}
    	}
    	/**
    	 * Shuffles field of bunnies, then grabs first non-mutant bunny
    	 * <br>and converts that bunny to a radio-active mutant vampire bunny.
    	 */
    	public void convertBunny()
    	{
    		//Collections.shuffle(bunnyList);
    		for (Bunny bunny : bunnyList)
    		{
    			if (! bunny.getRadioactive())
    			{
    				bunny.setRadioactive(true);
    				return;
    			}
    		}
    			
    	}
    	/**
    	 * Generates 1 random bunny and adds to field of bunnies.
    	 */
    	public void generateBunny()
    	{
    		boolean female;
    		String name="";
    		int i = (int)getRandom(20);
    		boolean ractive;
    		
    		// random sex
    		if (i>10)
    			female=true;
    		else
    			female=false;
    		
    		// random name
    		if (female)
    		{
    			int girlIndex = (int)getRandom(girlNames.size());
    			name=(girlNames.get(girlIndex));
    		}
    		else
    		{
    			int boyIndex = (int)getRandom(boyNames.size());
    			name=(boyNames.get(boyIndex));
    		}
    		
    		// random color
    		int icolor = (int)getRandom(6);
    		Color bunnyColor = Color.getColor(icolor);
    		
    		// random radioactiveness 2% chance
    		i = (int)getRandom(100);
    		if (i>2)
    			ractive = false;
    		else
    			ractive = true;
    		
    		// create bunny
    		Bunny bun = new Bunny(name, bunnyColor, female, 1, ractive);
    		bunnyList.add(bun);
    		
    		// TODO remove after debugging...//
    		/*
    		for (Bunny bunny : bunnyList)
    			System.out.println(bunny.toString());
    		//*/
    	}
    	
    	/**
    	 * Adds all names from both boys/girls files to appropiate Lists.
    	 */
    	public void initializeLists()
    	{
    		try
    		{
    			String inStr;
    			Scanner inFile = new Scanner(new FileInputStream(BOY_NAMES));
    			while (inFile.hasNextLine())
    			{
    				inStr = inFile.nextLine();
    				boyNames.add(inStr);
    			}
    			inFile.close();
    			
    			inFile = new Scanner(new FileInputStream(GIRL_NAMES));
    			while (inFile.hasNextLine())
    			{
    				inStr = inFile.nextLine();
    				girlNames.add(inStr);
    			}
    			inFile.close();
    			
    		}
    		catch(FileNotFoundException fnfe)
    		{
    			fnfe.printStackTrace();
    			System.out.println("File not found: " + BOY_NAMES);
    			System.out.println("File not found: " + GIRL_NAMES);
    		}
    	}
    	
    	/**
    	 * 
    	 */
    	public void printTotals()
    	{
    		int maleCount=0, femaleCount=0, vampireCount=0;
    		for (Bunny bunny : bunnyList)
    		{
    			if (bunny.getRadioactive())
    				vampireCount++;
    			else if (bunny.getSex())
    				femaleCount++;
    			else 
    				maleCount++;
    		}
    		System.out.println("Total males: " + maleCount + ".");
    		System.out.println("Total females: " + femaleCount + ".");
    		System.out.println("Total radioactive mutant vampires: " + 
    						vampireCount + ".");
    	}
    	/**
    	 * Prints out Girl names / Boy names.
    	 */
    	public void printList()
    	{
    //		 TODO remove after debugging...//
    		for (String gname : girlNames)
    			System.out.println((gname));
    		for (String bname : boyNames)
    			System.out.println((bname));
    		for (Bunny bunny : bunnyList)
    			System.out.println(bunny.toString());
    	}
    	/**
    	 * Prints out field of bunnies
    	 */
    	public void printFOB()
    	{
    		for (Bunny bunny : bunnyList)
    			System.out.println(bunny.toString());
    	}
    	/**
    	 * Get's a random number out of the number sent to the function.
    	 * <br>eg. If args = 50, will return a random double between 0 and 50.
    	 * @param numOutOf the number of randomness.
    	 * @return a double between 0 and the number sent to the function.
    	 */
    	public double getRandom(int numOutOf)
    	{
    		double temp = Math.random();
    		return (temp *= numOutOf);
    		/*
    		for (Iterator it = girlNames.iterator(); it.hasNext();) 
    		   System.out.println(((String)it.next()));
    		for (Iterator it = boyNames.iterator(); it.hasNext();) 
    		{
    		   String name = (String)it.next();
    		   System.out.println(name);
    		}
    		//*/
    	}
    	
    	
    }

Page 1 of 3 123 LastLast

Similar Threads

  1. Replies: 19
    Last Post: 08-28-2009, 01:49 AM
  2. ConcurrentModificationException with ArrayList
    By fogus in forum New To Java
    Replies: 3
    Last Post: 01-15-2009, 05:04 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •