Удалить первый элемент, найденный с определённой строкой из 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);
}
}