0

I've been trying to remove an element in ArrayList using the remove() object but it is still not deleting anything. I already checked the list stored in my array and everything is displaying fine, but when I try to remove an element, It is not working. My goal was the user would input a name to remove and it would search through the list that is equal to that name and remove it. The List Array is set as global.

Here is the code:

public static void removeStudents() {
    String removeName;

    System.out.println("******REMOVE STUDENTS******");
    System.out.print("Enter name you wish to remove: ");
    removeName = hold.nextLine();

    hold.nextLine();

    for (int x = 0; x < fullName.size(); x++) {
        if (fullName.get(x).equalsIgnoreCase(removeName)) {
            fullName.remove(x);
        }
    }       
}
13
  • 4
    You souldn't remove element from array which you actually iterate through Commented Dec 11, 2019 at 14:52
  • You will run into ConcurrentModificationException soon, because you are modifying the content of the collection you are iterating over. You should use an iterator to remove List elements instead. Commented Dec 11, 2019 at 14:53
  • Does this answer your question? How to avoid "ConcurrentModificationException" while removing elements from `ArrayList` while iterating it? Commented Dec 11, 2019 at 14:54
  • 1
    "when I try to remove an element, It is not working" In what way is it not working? Please edit your question to describe specifically what happens. Do you get any errors or exceptions? What do the messages say? Commented Dec 11, 2019 at 15:32
  • 1
    I wonder why there is a second readLine()? Is it possible that you are using a Scanner and the first readLine() is returning an empty string: stackoverflow.com/q/13102045/85421 Commented Dec 11, 2019 at 23:28

3 Answers 3

4

From Java 8 on, there is

Collection.removeIf(Predicate<? super E> filter)

You can easily remove elements matching specified criteria from a List, but you shouldn't do it while iterating that list because its indexes would change and that possibly leads to a ConcurrentModificationException as already mentioned in one of the comments below your question.

Do it like this:

public static void main(String[] args) {
    // provide sample data
    List<String> students = new ArrayList<>();
    students.add("Student 01");
    students.add("Student 02");
    students.add("Student 03");
    students.add("Student 04");
    students.add("Student 05");
    students.add("Student 06");
    // print the list once before any operation
    System.out.println("Before:\t" + String.join(", ", students));
    // remove elements matching certain criteria, here equality to "Student 03"
    students.removeIf(student -> student.equalsIgnoreCase("Student 03"));
    // print the list after removal of "Student 03"
    System.out.println("After:\t" + String.join(", ", students));
}

The output is

Before: Student 01, Student 02, Student 03, Student 04, Student 05, Student 06
After:  Student 01, Student 02, Student 04, Student 05, Student 06

Please note that this example just uses a List<String>, if you have a List<Student>, you would specify the criterium for removal like

students.removeIf(student -> student.getName().equalsIgnoreCase(removeName));
Sign up to request clarification or add additional context in comments.

4 Comments

sorry, but code posted in question is not affected by ConcurrentModificationException; neither size(), get() nor remove() will throw that exception. - this would be an issue if using the enhanced for loop (for-each)
Yes, my code just uses List<String>. But where did you get the student variable? because its giving me errors on that part.
@ReynardJoseph that variable is part of a lambda expression which are available since Java 8. What kind of error does it give you?
@user85421 Thanks for the hint, I have rephrased the part about the ConcurrentModificationException which doesn't get thrown by OP's code, but may be thrown in a similar context.
1

Lets say you have ArrayList of Strings with student names and its size is 5. Whenever you find the String to remove, in next iteration of for loop, you will skip one ArrayList element. You can overcome this by decrementing your for loop iterator, which is a working solution, but not the best. If your loop is on third element (fullName.get(2)) and it matches your deletion criteria, you will delete it and now have an ArrayList of 4 elements, not 5, where in next iteration (fileName.get(3)) you will actually skip one ArrayList element that had shifted to deleted elements position (whole ArrayList had shifted obviously).

public static void removeStudents(){
    String removeName;

    System.out.println("******REMOVE STUDENTS******");
    System.out.print("Enter name you wish to remove: ");
    removeName = hold.nextLine();

    hold.nextLine();

    for(int x=0 ; x<fullName.size() ; x++){
        if(fullName.get(x).equalsIgnoreCase(removeName)){
            fullName.remove(x);
            x--;
        }
    }       
}

This should work but as someone commented above, using an Iterator would be a better solution.

Comments

0
public static void removeStudents(){
    String removeName;

    System.out.println("******REMOVE STUDENTS******");
    System.out.print("Enter name you wish to remove: ");
    removeName = hold.nextLine();

    hold.nextLine();

    // collecting the objects that we want to delete
    List<String> foundList = new ArrayList<String>();

    for(int x = 0; x < fullName.size();x++){
        if(fullName.get(x).equalsIgnoreCase(removeName)){
            foundList.add(fullName.get(x));
        }
    }

    // delete objects
    fullName.removeAll(foundList);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.