John Wood
John Wood

Reputation: 45

Java: Run-time error during remove in an array list

I'm working on a project that manages a small student roster. One of the required functions is the ability to remove a student's record using the student ID identifier and for that remove function to give an error if the student ID does not exist.

The required test for this remove verification is to remove the same student ID twice and see if the error message is printed the second time the remove method is called.

The first remove method call is working and successfully deletes the element for the called student ID. However, the second remove is giving me a Concurrent Modification Exception error.

The following code creates the Student array list and calls the remove method (twice).

static ArrayList<Student> myRoster = new ArrayList<>();

public static void main(String[] args)
{
    // add students to the roster
    add("1", "John", "Smith", "[email protected]", "20", 
    88, 79, 59);
    add("2", "Suzan", "Erickson", "[email protected]", "19", 
    91, 72, 85);
    add("3", "Jack", "Napoli", "The_lawyer99yahoo.com", "19", 
    85, 84, 87);
    add("4", "Erin", "Black", "[email protected]", "22", 
    91, 98, 82);

    //loop through the ArrayList and for each element:
    remove("3");
    remove("3");

Here is the remove method. Here's my current thinking for how this should work:

*In order to first check to see if the student ID exists, I put the if/else to remove the student in an embedded if/else loop.

*I use contain to see if the array list contains the student ID. If it does, then the removal if/else executes. If it does not, it gives a failure printout and returns.

    public static void remove(String studentID)
    //remove student from roster by student ID
    //print error message if student is not found
    {
        for(Student b: myRoster)
        {
            String record = b.getStudentID();
            Boolean a = studentID.contains(studentID);
            if (a)
            {
                Boolean c = record.matches(studentID);
                if (c)
                {
                    myRoster.remove(b);
                    System.out.println("Student ID " + studentID + " was removed.");
                }
            else
                {
                    ;
                }  
            }
            else
            {
                System.out.println("Student ID does not exist.");
            }

Here is the error I'm getting:

java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at Roster.remove(Roster.java:48)
at Roster.main(Roster.java:28)
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at Roster.remove(Roster.java:48)
at Roster.main(Roster.java:28)

Any ideas?

Upvotes: 0

Views: 1214

Answers (3)

Kiryl
Kiryl

Reputation: 111

Try this:

for(Iterator<String> it = myRoster.iterator(); it.hasNext();) {
    String b = it.next();
    ...
    if (...) {
        it.remove();
        ...
    }
    ...
}

Upvotes: 0

pmorken
pmorken

Reputation: 784

You can't safely modify the contents of a List while iterating through it with an Iterator. Use a ListIterator to do this.

ListIterator<Student> it = myRoster.listIterator();
while (it.hasNext()) {
    Student b = it.next();
    if (b.getStudentId() == studentId) {
        it.remove(); // Removes b from myRoster
    }
    ...
}

Note that this wouldn't scale well if there were lots of students. You'd be better off with a Map<String, Student> to hold your roster, with the keys being the student IDs.

Upvotes: 1

trex
trex

Reputation: 11

Wouldn't you want to say the student ID doesn't exist in the first else portion of your loop that you've left blank?

if (a)
{
    Boolean c = record.matches(studentID);
    if (c)
    {
        myRoster.remove(b);
        System.out.println("Student ID " + studentID + " was removed.");
    }
    else
    {
        System.out.println("Student ID does not exist.");
    }  
}

Upvotes: 0

Related Questions