Удалить первый элемент, найденный с определённой строкой из ArrayList?

Я ПОЛНЫЙ новичок в кодировании. Я уже искал решение этой проблемы на этом форуме, но не смог найти его.

Прямо сейчас я застрял с кодированием метода removeFirstNote().

Каждый раз, когда я пытаюсь скомпилировать, я получаю сообщение об ошибке:

java.util.-ConcurrentModificationException

Вот что у меня так далеко... Это нужно сделать с помощью цикла FOR-EACH (школьное задание).

public class Notebook
{
    private ArrayList<String> notes;

    public Notebook()
    {
        notes = new ArrayList<String>();
    }

    public void removeFirstNote(String certainString)
    {   int noteNumber = 0;
        boolean removed = false;

        for (String note : notes){

            if(note.contains(certainString) && !removed){
                notes.remove(noteNumber);
                removed = true;

            } else {

                noteNumber++;
            }
        }   
    }

5 ответов

Просто break после вашего первого удаления,

    public void removeFirstNote(String certainString)
    {   
        int noteNumber = 0;
        //boolean removed = false; //No need

        for (String note : notes)
        {    
            if(note.contains(certainString))
            {
                notes.remove(noteNumber);
                //removed = true;
                break;
            } 
            else 
            {    
                noteNumber++;
            }
        }   
    }

Вам было бы интересно узнать, почему ConcurrentModificationException,
Для этого вы должны иметь представление о том, как for-each петля работает.
for-each цикл List будет внутренне преобразован в цикл for с итератором.

for (Iterator<String> iterator = mylist.iterator(); iterator.hasNext();)

когда вы используете это, а затем удалить элемент из списка, построенный Iterator не будет ничего знать об этом изменении, и будет ConcurrentModificationException,

Вы сталкиваетесь ConcurrentModificationException потому что вы делаете две операции на одном list вовремя. т.е. зацикливание и удаление в то же время.

Чтобы избежать этой ситуации, используйте Iterator, который гарантирует безопасное удаление элемента из списка.

 Iterator<String> it = notes.iterator();
        while (it.hasNext()) {
            if (condition) {
                it.remove();
                break;
            }
        }

Если без итератора,

1) вам нужно использовать другой список

2) Добавьте все элементы к нему.

3) Цикл по первоначальному списку

3) когда условие выполнено, remove из оригинала list

Пытаться:

for(String note : notes){
   if(!notes.contains(certainString){
      continue;
   }
   if(notes.contains(certainString)== true){
      System.out.println("String: " + certainString + " has been removed");
      notes.remove(certainString);
      break;
   }
   else{
     // do this
   }

Вы можете свести это к следующему:

public void removeFirstNote(String certainString) {
 for (String note: notes) {
  if (note.contains(certainString)) {
    notes.remove(note);
    break; // exit this loop.
  } 
 }
}

это более эффективно - нет смысла повторяться, когда вы нашли то, что искали.

надеюсь это поможет.

Винни Флитвуд

Вы не можете зацикливать список и удалять элементы одновременно. Если вы должны использовать цикл for, я предлагаю сначала пройтись по списку и отметить элемент, который подходит, а затем удалить его.

public void removeFirstNote(String certainString) {
  int noteNumber = 0;
  boolean removed = false;
  int index = -1;

  for (String note : notes) {

     if (note.contains(certainString) && !removed) {
        index = noteNumber;
        removed = true;
        //if your teacher allows you to, you can break the loop here and it all becomes easier
     } else {

        noteNumber++;
     }
  }
  if (index != -1) {
     notes.remove(index);
  }

}

Другие вопросы по тегам