删除链接列表中所有出现的单词

Removing all occurrencs of a word in a LinkedList

我正在尝试获取一种方法,该方法可以从链接列表(单词)中删除所有出现的单词。我所做的方法删除了所有事件,但不是第一个?这是我的删除方法:

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"

运行 "add" 的 removeAll 之后的输出将是:

 words = "add","hello"

有人知道为什么第一次出现的内容没有被删除吗?谢谢!

如果像这样向前遍历列表并删除项目,则不会删除所有相邻的匹配项目。

例如,如果您的列表是 [add, add] 而您要删除 add:

  • 索引初始为0,列表为[add, add]
  • 您在索引 0 找到 add
  • 删除元素 0,现在列表为 [add]
  • 增加索引,现在index == 1
  • 索引现在大于或等于列表大小,因此您打破循环
  • 最终名单是[add]

所以你 "skipped over" 第二个添加很有效。

解决此问题的一种方法是在删除元素后递减 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 以利用列表内部实现的知识,以允许高效的迭代和删除。