Page 1 of 2 12 LastLast
Results 1 to 20 of 30
  1. #1
    Propinquity is offline Member
    Join Date
    Oct 2013
    Posts
    63
    Rep Power
    0

    Default Exception in thread "main" java.util.ConcurrentModificationException?

    I've never seen this error and I honestly don't understand why or how it applies to my code despite looking it up. Could someone please illustrate what this is and why it is happening?
    Error Message:
    Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(Unk nown Source)
    at java.util.ArrayList$Itr.next(Unknown Source)
    at SongCollection.filterYear(SongCollection.java:13)
    at GazillionSongs.main(GazillionSongs.java:21)
    Also, for some reason, no matter what I do, my Range's max and min keeps remaining 0.
    I checked the parsing by printing the max and min values all throughout the method and printing the tokens produced by the StringTokenizer.
    The method parses fine...but for some reason the values don't change. I'm not quite understanding this either.

    SongCollection class:
    Java Code:
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Scanner;
    import java.util.*;
    
    public class SongCollection {
    	ArrayList<Song> songs2;
    
    	public SongCollection(ArrayList<Song> songs) {
    		this.songs2 = songs;
    	}
    
    	public void filterYear(Range r) {
    		for (Song song : songs2) {
    			if ((song.year > (r.getMax())) || (song.year < r.getMin())) {
    				songs2.remove(song);
    			}
    		}
    	}
    
    	public void filterRank(Range r) {
    		for (Song song : songs2) {
    			if ((song.rank > (r.getMax())) || (song.rank < r.getMin())) {
    				songs2.remove(song);
    			}
    		}
    	}
    
    	public void filterArtist(String s) {
    		for (Song song : songs2) {
    			if (!(((song.artist).equals(s)))) {
    				songs2.remove(song);
    			}
    		}
    	}
    
    	public void filterTitle(String s) {
    		for (Song song : songs2) {
    			if (!(((song.title).equals(s)))) {
    				songs2.remove(song);
    			}
    		}
    	}
    
    	public void sortYear() {
    
    	}
    
    	public void sortRank() {
    
    	}
    
    	public void sortArtist() {
    
    	}
    
    	public void sortTitle() {
    
    	}
    
    }
    GazillionSongs class:

    Java Code:
    import java.util.*;
    import java.io.*;
    
    public class GazillionSongs {
    	public static void main(String[] args) throws FileNotFoundException {
    		Song test = new Song();
    		File f = new File("agazillionsongs.txt");
    		Scanner tokens = new Scanner(f);
    		ArrayList<Song> songs = new ArrayList<Song>();
    		while ((tokens.hasNextLine())) {
    			songs.add(test.parse(tokens.nextLine()));
    		}
    
    		Range r = new Range();
    		System.out.println("Max = " + r.getMax());
    		System.out.println("Min = " + r.getMin());
    		r.parse("1998-2000");
    		System.out.println("Max = " + r.getMax());
    		System.out.println("Min = " + r.getMin());
    
    		SongCollection test2 = new SongCollection(songs);
    		test2.filterYear(r);
    		System.out.println(test2);
    	}
    }
    Song class:

    Java Code:
    import java.util.Scanner;
    import java.util.StringTokenizer;
    
    public class Song {
    	int year;
    	int rank;
    	String artist;
    	String title;
    
    	public static Song parse(String s) {
    		StringTokenizer tokenizer = new StringTokenizer(s, "\t");
    		Song instance = new Song();
    		instance.year = Integer.parseInt(tokenizer.nextToken());
    		instance.rank = Integer.parseInt(tokenizer.nextToken());
    		instance.artist = (tokenizer.nextToken());
    		instance.title = (tokenizer.nextToken());
    		return instance;
    	}
    
    	public int getYear() {
    		return year;
    	}
    
    	public int getRank() {
    		return rank;
    	}
    
    	public String getArtist() {
    		return artist;
    	}
    
    	public String getTitle() {
    		return title;
    	}
    
    	public String toString() {
    		String output = "Year = " + year + "\nRank = " + rank + "\nArtist = "
    				+ artist + "\nTitle = " + title;
    		return output;
    	}
    }
    Range class:

    Java Code:
    import java.util.StringTokenizer;
    
    public class Range {
    	private int min;
    	private int max;
    
    	public static Range parse(String s) {
    		StringTokenizer tokenizer = new StringTokenizer(s, "-");
    		Range instance = new Range();
    		if (s.contains("-")) {
    			instance.min = Integer.parseInt(tokenizer.nextToken());
    			instance.max = Integer.parseInt(tokenizer.nextToken());
    
    		} else if (!(s.contains("-"))) {
    			{
    				instance.min = Integer.parseInt(s);
    				instance.max = Integer.parseInt(s);
    			}
    		}
    		return instance;
    	}
    
    	public boolean contains(int n) {
    		if (n > min && n < max) {
    			return true;
    		} else if (n == min && n == max) {
    			return true;
    		} else {
    			return false;
    		}
    	}
    
    	public int getMin() {
    		return min;
    	}
    
    	public int getMax() {
    		return max;
    	}
    }

  2. #2
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    SW Missouri
    Posts
    17,457
    Rep Power
    25

    Default Re: Exception in thread "main" java.util.ConcurrentModificationException?

    Can you post the program's output that shows what you are describing?


    One problem I see is the use of static methods. Change the parse() method to be an instance method.
    If you don't understand my response, don't ignore it, ask a question.

  3. #3
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    3,618
    Rep Power
    5

    Default Re: Exception in thread "main" java.util.ConcurrentModificationException?

    There is nothing wrong with asking multiple questions at a time using different threads. But please, at least respond to those who provide you answers before starting another thread.

    Regards,
    Jim
    The Java™ Tutorial | SSCCE | Java Naming Conventions
    Poor planning our your part does not constitute an emergency on my part.

  4. #4
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,537
    Blog Entries
    7
    Rep Power
    20

    Default Re: Exception in thread "main" java.util.ConcurrentModificationException?

    The 'new for loop' creates an Iterator behind the scenes and you remove items from your collector directly (i.e. not through the Iterator).

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

  5. #5
    Propinquity is offline Member
    Join Date
    Oct 2013
    Posts
    63
    Rep Power
    0

    Default Re: Exception in thread "main" java.util.ConcurrentModificationException?

    Quote Originally Posted by Norm View Post
    Can you post the program's output that shows what you are describing?


    One problem I see is the use of static methods. Change the parse() method to be an instance method.
    We're required to use static methods for some reason. I'm not sure why.

  6. #6
    Propinquity is offline Member
    Join Date
    Oct 2013
    Posts
    63
    Rep Power
    0

    Default Re: Exception in thread "main" java.util.ConcurrentModificationException?

    This is the program's output. I changed my if statement in the Range class to
    Java Code:
    	if (s.contains("-")){
    			System.out.println("First token:" + (Integer.parseInt(tokenizer.nextToken())));
    			System.out.println("Second token:" + (Integer.parseInt(tokenizer.nextToken())));
    		
    		} else if (!(s.contains("-"))){{
    			System.out.println(Integer.parseInt(s));
    			System.out.println(Integer.parseInt(s));
    			}
    		}
    Max = 0
    Min = 0
    First token:1998
    Second token:2000
    Max = 0
    Min = 0

  7. #7
    Propinquity is offline Member
    Join Date
    Oct 2013
    Posts
    63
    Rep Power
    0

    Default Re: Exception in thread "main" java.util.ConcurrentModificationException?

    Quote Originally Posted by JosAH View Post
    The 'new for loop' creates an Iterator behind the scenes and you remove items from your collector directly (i.e. not through the Iterator).

    kind regards,

    Jos
    I don't think I completely understand this. :(
    We haven't learned about Iterators or Collections yet, just ArrayLists, and searching and sorting methods.

  8. #8
    Propinquity is offline Member
    Join Date
    Oct 2013
    Posts
    63
    Rep Power
    0

    Default Re: Exception in thread "main" java.util.ConcurrentModificationException?

    Quote Originally Posted by Propinquity View Post
    I don't think I completely understand this. :(
    We haven't learned about Iterators or Collections yet, just ArrayLists, and searching and sorting methods.
    I looked up the Iterator and how to use it, but I couldn't get it to work, because I want to be able to call the variables of an Object, (i.e song.year) and I don't know how to do that except with a for-each loop where it's declared.
    I decided to make two ArrayLists, then add the songs I need to remove to the list, then use removeAll, like so:
    Java Code:
    for (Song song1: songs2){
    			if (song1.year > (r.getMax()) || (song1.year) < (r.getMax()))
    				itemsToRemove.add(song1);
    			}
    		songs2.removeAll(itemsToRemove);
    		}

  9. #9
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    SW Missouri
    Posts
    17,457
    Rep Power
    25

    Default Re: Exception in thread "main" java.util.ConcurrentModificationException?

    The for:each loop uses an Iterator. If you use the older style for loop with an int variable and the get() method you shouldn't get the ConcurrentModificationException.
    To keep removals from being a problem start at the end of the list and work towards the first item.
    If you don't understand my response, don't ignore it, ask a question.

  10. #10
    jashburn is offline Senior Member
    Join Date
    Feb 2014
    Posts
    219
    Rep Power
    1

    Default Re: Exception in thread "main" java.util.ConcurrentModificationException?

    I don't think I completely understand this. :(
    Let me try to explain this from the beginning.

    Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(Unk nown Source)
    at java.util.ArrayList$Itr.next(Unknown Source)
    at SongCollection.filterYear(SongCollection.java:13)
    The filterYear method contains an enhanced for-loop, where during iteration it may also remove elements from songs2 via songs2.remove(song).

    songs2 is an ArrayList, and according to the documentation for ArrayList at ArrayList (Java Platform SE 7 ),

    The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException.
    So you have:
    1. the ConcurrentModificationException
    2. structural modification on songs2 via songs2.remove(song) rather than via songs2's iterator's add/remove methods

    The 3rd condition to fulfil so that ConcurrentModification is thrown is the use of the class's iterator or listIterator.

    Referring to https://jcp.org/aboutJava/communityp...anced-for.html, under the Semantics section,

    If Expression is an instance of java.util.Collection, the enhanced for statement is shorthand for this:

    for ( Iterator<T> $i = Expression.iterator(); $i.hasNext(); ) {
    Type Identifier = $i.next();
    Statement
    }
    Since ArrayList is an instance of Collection (ArrayList implements List, and List extends Collection), the enhanced for-loop, as Jos and Norm mentioned earlier, creates an iterator behind the scene in the way as quoted above. This happens during compilation. In other words, you can think of it as the compiler converting the enhanced for-loop into a for loop that uses songs2's iterator.

    Hth!

  11. #11
    Propinquity is offline Member
    Join Date
    Oct 2013
    Posts
    63
    Rep Power
    0

    Default Re: Exception in thread "main" java.util.ConcurrentModificationException?

    Quote Originally Posted by jashburn View Post
    Let me try to explain this from the beginning.



    The filterYear method contains an enhanced for-loop, where during iteration it may also remove elements from songs2 via songs2.remove(song).

    songs2 is an ArrayList, and according to the documentation for ArrayList at ArrayList (Java Platform SE 7 ),



    So you have:
    1. the ConcurrentModificationException
    2. structural modification on songs2 via songs2.remove(song) rather than via songs2's iterator's add/remove methods

    The 3rd condition to fulfil so that ConcurrentModification is thrown is the use of the class's iterator or listIterator.

    Referring to https://jcp.org/aboutJava/communityp...anced-for.html, under the Semantics section,



    Since ArrayList is an instance of Collection (ArrayList implements List, and List extends Collection), the enhanced for-loop, as Jos and Norm mentioned earlier, creates an iterator behind the scene in the way as quoted above. This happens during compilation. In other words, you can think of it as the compiler converting the enhanced for-loop into a for loop that uses songs2's iterator.

    Hth!
    That makes much more sense. Thank you.
    Does anyone know why the variables min and max are failing to be redefined for the Range class?

  12. #12
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    3,618
    Rep Power
    5

    Default Re: Exception in thread "main" java.util.ConcurrentModificationException?

    Actually, the reason the enhanced for loop works is because of the implemention of Iterable<T>

    Regards,
    Jim
    Last edited by jim829; 03-08-2014 at 05:26 PM.
    The Java™ Tutorial | SSCCE | Java Naming Conventions
    Poor planning our your part does not constitute an emergency on my part.

  13. #13
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    SW Missouri
    Posts
    17,457
    Rep Power
    25

    Default Re: Exception in thread "main" java.util.ConcurrentModificationException?

    variables min and max are failing to be redefined for the Range class?
    Which instance of the Range class are you looking at? The changes are made in one, the code looks at another.
    Removing "static" from the method would be a step towards fixing the problem.
    If you don't understand my response, don't ignore it, ask a question.

  14. #14
    Propinquity is offline Member
    Join Date
    Oct 2013
    Posts
    63
    Rep Power
    0

    Default Re: Exception in thread "main" java.util.ConcurrentModificationException?

    Quote Originally Posted by Norm View Post
    Which instance of the Range class are you looking at? The changes are made in one, the code looks at another.
    Removing "static" from the method would be a step towards fixing the problem.
    I wish I could remove static, but it's a requirement for the assignment.
    I'm referring to my test case, when I called the method in my main:
    Java Code:
    r.parse("1998-2000"); //line 17 in main

  15. #15
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    SW Missouri
    Posts
    17,457
    Rep Power
    25

    Default Re: Exception in thread "main" java.util.ConcurrentModificationException?

    How many instances of the Range class are created?
    Which instance gets the values?
    Which instance is used to print the messages?

    To see how many instances are created, add a constructor to the Range class and have it print a message.
    If you don't understand my response, don't ignore it, ask a question.

  16. #16
    Propinquity is offline Member
    Join Date
    Oct 2013
    Posts
    63
    Rep Power
    0

    Default Re: Exception in thread "main" java.util.ConcurrentModificationException?

    Quote Originally Posted by Norm View Post
    How many instances of the Range class are created?
    Which instance gets the values?
    Which instance is used to print the messages?

    To see how many instances are created, add a constructor to the Range class and have it print a message.

    The new output is:
    message
    Max = 0
    Min = 0
    message
    First token:1998
    Second token:2000
    Max = 0
    Min = 0


    So there are two instances? Is that the problem?
    Because I'm making an new instance of Range inside the parse method....but I don't know how else to make it return an instance, or how to make it modify the Range class when it runs.

  17. #17
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    SW Missouri
    Posts
    17,457
    Rep Power
    25

    Default Re: Exception in thread "main" java.util.ConcurrentModificationException?

    A couple of things:
    1) you do NOT need an instance of a class to call a static method. The compiler should warn you about that. Use the classname as here: Classname.staticMethod()
    2) What is done with the instance of the Range class that is returned by the parse method?
    If you don't understand my response, don't ignore it, ask a question.

  18. #18
    Propinquity is offline Member
    Join Date
    Oct 2013
    Posts
    63
    Rep Power
    0

    Default Re: Exception in thread "main" java.util.ConcurrentModificationException?

    Quote Originally Posted by Norm View Post
    A couple of things:
    1) you do NOT need an instance of a class to call a static method. The compiler should warn you about that. Use the classname as here: Classname.staticMethod()
    2) What is done with the instance of the Range class that is returned by the parse method?
    That helps a lot. Thank you! I think I figured out what the problem is.

  19. #19
    Propinquity is offline Member
    Join Date
    Oct 2013
    Posts
    63
    Rep Power
    0

    Default Re: Exception in thread "main" java.util.ConcurrentModificationException?

    Despite having a for-each loop that works, I'm still getting a ConcurrentModificationException.
    This is happening for the filterArtist and filterTitle methods only. filterRank and filterString both work.

  20. #20
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,537
    Blog Entries
    7
    Rep Power
    20

    Default Re: Exception in thread "main" java.util.ConcurrentModificationException?

    Quote Originally Posted by Propinquity View Post
    Despite having a for-each loop that works, I'm still getting a ConcurrentModificationException.
    This is happening for the filterArtist and filterTitle methods only. filterRank and filterString both work.
    Show us your updated code for the filterXXX( ... ) methods.

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

Page 1 of 2 12 LastLast

Similar Threads

  1. Replies: 1
    Last Post: 11-02-2012, 11:38 PM
  2. Replies: 11
    Last Post: 09-04-2012, 04:33 AM
  3. Replies: 4
    Last Post: 05-07-2010, 07:58 PM
  4. Exception in thread "main" java.util.NoSuchElementException
    By vileoxidation in forum New To Java
    Replies: 5
    Last Post: 09-17-2008, 07:29 AM
  5. Replies: 5
    Last Post: 05-14-2008, 01:43 PM

Posting Permissions

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