-1

是否应该允许您从当前在 foreach 循环中迭代的集合中删除一个项目?

如果是这样,正确的行为应该是什么?

4

9 回答 9

3

我可以采用相当复杂的 Collection 来支持跟踪集合更改以保持位置信息正确的枚举器。即使它确实需要做出一些妥协或假设。出于这个原因,大多数图书馆只是简单地禁止这样的事情或在他们的文档中抱怨意外的行为。

因此,最安全的方法是循环。收集对需要删除的事物的引用,然后使用收集到的引用从原始集合中删除项目。

于 2009-06-11T09:13:48.853 回答
1

这真的取决于语言。有些人只是敲击一个阵列并在您更改该阵列时爆炸。有些使用数组并且不会爆炸。有些人调用迭代器(它们完全更健壮)并且运行得很好。

于 2009-06-11T09:10:31.700 回答
1

通常,在循环中修改集合foreach是一个坏主意,因为程序不知道您的意图。您的意思是在更改之前遍历所有项目,还是希望它只与新配置一起使用?已经循环的项目呢?

相反,如果您想修改集合,请创建一个预定义的要循环的项目列表,或者使用索引循环。

于 2009-06-11T09:16:03.903 回答
1

诸如哈希表和字典之类的一些集合没有“位置”的概念,并且通常不能保证迭代的顺序。因此,在迭代时允许删除项目是相当困难的。

于 2009-06-11T09:18:31.717 回答
0

反向迭代并一项一项删除项目......这应该是正确的解决方案。

于 2009-06-11T09:47:32.030 回答
0

不,你不应该。正确的行为应该是表示遇到了潜在的并发问题,但是这是用您选择的语言完成的(抛出异常、返回错误代码、raise() 一个信号)。

如果您在迭代其元素时修改数据结构,则迭代器可能不再有效,这意味着您可能会处理不再属于集合的对象。如果您想根据一些更复杂的符号过滤元素,您可以执行以下操作(在 Java 中):

List<T> toFilter = ...;
List<T> shadow;
for ( T element : toFilter )
    if ( keep(element) )
         shadow.add(element);

/* If you'll work with toFilter in the same context as the filter */
toFilter = shadow;

/* Alternatively, if you want to modify toFilter in place, for instance if it's
 * been given as a method parameter
 */
toFilter.clear();
toFilter.addAll(shadow);
于 2009-06-11T09:48:54.820 回答
0

从您正在迭代的集合中删除项目以显式使用迭代器的最佳方法。例如。

List<String> myList = ArrayList<String>();
Iterator<String> myIt = myList.iterator();

while (myIt.hasNext()) {
    myIt.remove();
}
于 2009-06-11T10:02:48.490 回答
0

你必须先了解 foreach 的概念,实际上它取决于编程语言。但作为一般答案,您应该避免在 foreach 中更改您的集合

于 2009-06-11T09:14:54.063 回答
0

只需使用标准 for 循环,向后遍历项目集合,您应该可以随时删除项目。

于 2009-06-11T09:23:49.427 回答