Java 从列表中动态删除元素

Java 从列表中动态删除元素,java,arraylist,Java,Arraylist,我在遍历列表时删除列表元素时遇到问题。代码: For (WebElement element: list){ if (!element.isEnabled() || !element.isSelected()){ list.remove(element); } } 我得到了一个我完全理解的ConcurrentModificationException。在遍历列表的循环中,我正在从列表中删除一项。直觉上,这会破坏循环的索引 我的问题是,我应该如何从列表中删除未启用

我在遍历列表时删除列表元素时遇到问题。代码:

For (WebElement element: list){
    if (!element.isEnabled() || !element.isSelected()){
        list.remove(element);
    }
}
我得到了一个我完全理解的
ConcurrentModificationException
。在遍历列表的循环中,我正在从列表中删除一项。直觉上,这会破坏循环的索引


我的问题是,我应该如何从列表中删除未启用
或未选择
的元素?

从循环列表中删除元素的最简单方法是使用
列表迭代器
并使用例程删除元素

在遍历列表时修改列表,除了使用迭代器之外,还会导致未定义的行为。您必须显式地使用迭代器:

Iterator<WebElement> iter = list.iterator();
while (iter.hasNext()) {
    WebElement element = iter.next();
    if (!element.isEnabled() || !element.isSelected()) {
        iter.remove();
    }
}
Iterator iter=list.Iterator();
while(iter.hasNext()){
WebElement=iter.next();
如果(!element.isEnabled()| |!element.isSelected()){
iter.remove();
}
}

有关更多信息,请参见。

ConcurrentModificationException
的结果是,for-each语法只是使用迭代器接口的语法糖

列表迭代器具有所谓的“fail fast”属性,这意味着除了迭代器提供的接口之外,对列表所做的任何更改都会立即使所述迭代器无效。尝试使用无效迭代器会触发异常

@Claudiu已经发布了这段代码,但为了清楚起见,我也将把它放在这里。为了完成您想要做的事情,您必须放弃花哨的语法并使用一个简单的迭代器

Iterator<WebElement iter = list.iterator();
while (iter.hasNext()) {
    WebElement element = iter.next();
    if (!element.isEnabled() || !element.isSelected()) {
        iter.remove();
    }
}

Iterator其他人建议使用列表迭代器。这对我来说很有用,但不幸的是,它依赖于一个方法,
remove()
,这个方法被
Iterable
接口认为是可选的

引用Javadoc,nevermore(我的重点):

作废删除()

从基础集合中移除由返回的最后一个元素 迭代器(可选操作)

对我来说更有用的是删除列表

List<E> removed = new ArrayList<E>();
for(E element : list) {
    if(someCondition) removed.add(element);
}
list.removeAll(removed);
List removed=new ArrayList();
对于(E元素:列表){
如果(某些条件)被删除,则添加(元素);
}
list.removeAll(已删除);

这还有一个额外的好处,就是为您提供删除内容的历史记录,就像删除方法一样。

Hmm我明白了。因此,如果我想将
迭代器
转换回
列表
,有没有比在循环中逐个添加每个元素更简单的方法?这不会将
列表
转换为
迭代器
迭代器
只是一个作用于该列表本身的对象-它是一个在列表中进行迭代的接口。当你调用
iter.remove()
时,它实际上是在修改底层列表。我非常喜欢这个(+1)。然而,元素E应该有一个适当的相等覆盖method@GETah不一定。如果没有它,它会工作得很好,甚至可能是首选。你可能会发现它们来自工厂方法,在工厂方法中,你对equals方法的需求要小得多,严格依赖于equals的引用。哇,我也很喜欢这个!非常好的开箱思考。更新内容包括了我为什么更喜欢迭代器上的
remove
方法的原因。我不知道这是否一定是最简单的方法
remove()
迭代器
界面上的一项可选功能。还值得注意的是,
remove()
位于
Iterator
上,仅由
listediterator
继承。