Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Alexandra Bonono
9,817 PointsI get "Runtime Exception: java.util.ConcurrentModificationException" for challenge task 3
Java /Java Data Structures /Efficiency! /Don't Stop Believin' Challenge Task 3: Thsi is the code I used :
public void fixVideoTitle(Course course, String oldTitle, String newTitle) {
Map<String, Video> mappedVideos = videosByTitle(course);
for (Map.Entry<String, Video> entry : mappedVideos.entrySet()){
if (entry.getKey() == oldTitle){
mappedVideos.remove(entry.getKey());
mappedVideos.put(newTitle, entry.getValue());
}
}
}
But i got "Runtime Exception: java.util.ConcurrentModificationException" I want to know what is wrong with the code, I now understand that what I am trying to do is not good by why?
2 Answers
Simon Coates
28,695 PointsI think Java doesn't like you altering collections within a foreach loop. The foreach loop uses an iterator. This is a fancy bit of code that remembers where it's up to in the loop. If you alter the variable it's currently acting on, it throws an exception.
You can avoid using the foreach for this challenge. the following seems to work:
import com.example.model.Course;
import com.example.model.Video;
import java.util.Map;
import java.util.HashMap;
public class QuickFix {
public void addForgottenVideo(Course course) {
// TODO(1): Create a new video called "The Beginning Bits"
Video v = new Video("The Beginning Bits");
// TODO(2): Add the newly created video to the course videos as the second video.
course.getVideos().add(1, v);
}
public void fixVideoTitle(Course course, String oldTitle, String newTitle) {
Map<String, Video> mappedVideos = videosByTitle(course);
Video toChange = mappedVideos.get(oldTitle);
if(toChange != null) {
toChange.setTitle(newTitle);
mappedVideos.remove(oldTitle);
mappedVideos.put(newTitle, toChange);
}
}
public Map<String, Video> videosByTitle(Course course) {
Map<String, Video> nameToVid = new HashMap<String, Video>();
for(Video v: course.getVideos())
{
nameToVid.put(v.getTitle(), v);
}
return nameToVid;
}
}
Alexandra Bonono
9,817 PointsHi Simon, so I can only loop through the collection do any others actions but I cannot change them? I found another answer for the challenge and I understandood it, now I think it makes sense, thanks Simon
Alexandra Bonono
9,817 PointsThank you for correcting fixVideoTitle(), this look great.
Simon Coates
28,695 Pointsit's possible to remove an item while inside a foreach loop, but it's complicated (see https://stackoverflow.com/questions/223918/iterating-through-a-collection-avoiding-concurrentmodificationexception-when-re ). it's easier to avoid the problem.
Alexandra Bonono
9,817 PointsOk , i will take is as a bad practice to avoid, thank you.
Simon Coates
28,695 PointsSimon Coates
28,695 PointsI'm not an expert, but a lot of the time it's possible to avoid the error. You can use the foreach loop item and just store what exactly you want to remove. eg.