Удаление всех вхождений слова в списке ссылок



Я пытаюсь получить метод, который удаляет все вхождения слова из связанного списка (слов). Метод, который я сделал, удаляет все случаи, но не первый? Вот мой метод удаления:



public void removeAll(){
for(int x = 0; x < words.size(); x++){
if(words.get(x).equalsIgnoreCase(inputWord)){
words.remove(x);
}
}
out2.setText("Word '" + inputWord + "' all occurrence's have been removed.");
System.out.println(words);
}


Если бы слова были:



 words = "add","hello","add","add"


Вывод после запуска removeAll для " add " будет следующим:



 words = "add","hello"


У кого-нибудь есть идея, почему первое событие не было бы удалено? Спасибо!

554   1  

1 ответ:

Если вы пройдете вперед по списку, подобному этому, и удалите элементы, вы не удалите все соседние соответствующие элементы.

Например, если ваш список [add, add] и вы удаляете add:

  • индекс изначально равен 0, список - [add, add].
  • Вы найдете add в индексе 0.
  • удалить элемент 0, теперь список [add].
  • индекс инкремента, теперь index == 1.
  • индекс теперь больше или равен размеру списка, поэтому вы разрываете цикл
  • окончательный список есть [add].

Так эффективно вы "пропустили" второе добавление.

Один из способов исправить это, чтобы уменьшить index после того, как вы удалили элемент. Некоторые люди (требуется цитирование) неодобрительно относятся к изменению переменной итерации внутри тела цикла for. Это делает правильность немного труднее рассуждать.

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

for(int x = words.size() - 1; x >= 0; x--){

Однако наилучшим подходом является использование Iterator:

Iterator<String> it = words.iterator();
while (it.hasNext()) {
  if (it.next().equalsIgnoreCase(inputWord)) {
    it.remove();
  }
}
Обратите внимание, что LinkedList.get(int) является операцией O(list.size()), поэтому вы действительно не хотите использовать ее для доступа к своим элементам в последовательности. Iterator может быть реализован для использования знаний о внутренней реализации списка, чтобы обеспечить эффективную итерацию и удаление.

Comments

    Ничего не найдено.