RemoveAt()和Remove()的区别

时间:2018-09-05 18:22:04

标签: c# list

我只是注意到我测试了RemoveAt()和Remove()这两个方法时有些尴尬,但是它们的工作方式不同,我想知道是否有人可以举例说明其原因。基本上,在此示例中,唯一成功从列表中删除特定项目的方法是Remove()。

List<int> testList = new List<int>{1,76,3,4,5,76,76,8};

public void RemoveElements()
{
    for (int i = 0; i < testList.Count; i++)
    {
        //WORKS
        testList.Remove(76); //A 

        // DOES NOT WORK
        //if(testList[i] == 76) testList.Remove(testList[i]); //B 

        // DOES NOT WORK EITHER
        // if(testList[i] == 76) testList.RemoveAt(i); //C
    }
}

A的输出为:1、3、4、5、8 B的输出为:1、3、4、5、76、8 C的输出是:1、3、4、5、76、8

谢谢您的时间!

4 个答案:

答案 0 :(得分:2)

按索引删除项目会更改后面的项目的索引。这可能导致跳过某些项目。如果要在遍历列表时使用RemoveAt,请尝试反向迭代。

答案 1 :(得分:1)

RemoveRemoveAt函数实际上在您的代码中正常工作。但是,如果要遍历列表,则使用RemoveAt是更好的函数,因为Remove必须再次搜索列表以查找出现76的第一种情况,而{ {1}}已经知道删除该项目的确切索引。

由于您遍历列表的方式而出现问题。

当您遍历列表并从列表中删除项目时,列表会向左移动一个索引以填充RemoveAt索引仍在同一位置时刚刚删除的项目(跳过下一个项目) 。
通常,最好的做法是,如果要从列表中删除元素,则向后遍历列表,因为终点取决于它达到0,并且每次处理列表向左移动时都不会跳过下一个元素。

i

答案 2 :(得分:1)

这是您的列表开头的内容:

i:             0   1   2   3   4   5   6   7
testList[i]:   1  76   3   4   5  76  76   8

现在考虑当i == 5在循环迭代期间会发生什么,这意味着testList[i]是两个相邻76es中的第一个。运行版本B或C中的代码将从testList中删除元素5,从而导致其后的元素向下移动一个索引。因此testList[6]原本是76,现在是8;和testList[7](原为8)现在已超出列表的末尾。下一次循环运行时,它将使用i == 6,这意味着您的代码将考虑值8,而不是76es中的秒。第二个76已被完全跳过。

这是hatchet对您的问题进行评论的原因,该问题表示如果必须遍历列表,则应相反进行。如果要向后迭代,则删除元素将元素的位置在列表中进一步往下移都没关系,因为您已经处理了这些元素。当然,更好的方法仍然是使用根本不需要迭代的解决方案,例如List<T>.RemoveAll

答案 3 :(得分:0)

Remove从集合中删除等于您指定的元素的元素。 RemoveAt删除指定位置的元素。