[英]Remove multiple items from ArrayList during iterator
在使用迭代器迭代 ArrayList 时从 ArrayList 中删除多个项目是否安全?
Iterator<String> iterator = nameList.iterator();
while(iterator.hasNext()){
String s = iterator.next();
List<String> list = work(s);
for (String s1 : list) {
nameList.remove(s1);
}
}
work()
方法返回在 while 循环运行期间应从 nameList 中删除的名称列表。
不,它不安全,可以抛出ConcurrentModificationException
。 您可以在临时List
收集要删除的所有元素,然后在while循环之后调用list.removeAll(tmpList)
来执行删除。
Iterator<String> iterator = nameList.iterator();
List<String> removed = new ArrayList<>();
while(iterator.hasNext()){
String s = iterator.next();
removed.addAll(work(s));
}
list.removeAll(removed);
我意识到这可能效率较低,因为你可能会在String
上调用work(s)
应该已经从List
删除了。 这可以通过将tempList
更改为Set
来改进,并且只调用不在Set
中的String
的work(s)
:
Iterator<String> iterator = nameList.iterator();
Set<String> removed = new HashSet<>();
while(iterator.hasNext()){
String s = iterator.next();
if (!removed.contains(s)) {
removed.addAll(work(s));
}
}
list.removeAll(removed);
如果使用故障安全的ListIterator,则可以实现逻辑。 以下是一个基本示例:
Set<String> removed = new HashSet<>();
ArrayList<String> nameList = new ArrayList<String>();
ListIterator<String> iterator = nameList.listIterator();
while(iterator.hasNext()){
String s = iterator.next();
if (!removed.contains(s)) {
removed.addAll(work(s));
}
}
nameList.removeAll(removed);
System.out.println(nameList);
根据您的逻辑,您必须考虑性能。 如果性能不是一个因素,您可以继续通过ListIterator从列表中添加/删除。
如前面的答案所述,从迭代列表中删除项目并不安全。 这是抛出ConcurrentModificationException
的代码:
List<String> list = new ArrayList<>(Arrays.asList("1", "2", "3"));
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String s = iterator.next();
list.remove("1");
}
您可以使用Iterator.remove()
(而不是nameList.remove(s)
)。
Iterator<String> iterator = nameList.iterator();
while(iterator.hasNext()){
String s = iterator.next();
iterator.remove();
}
还要考虑nameList.clear()
和nameList.removeAll(elementsToRemove)
。
迭代器在对其底层 collections 进行任何修改后通常无效,除非通过迭代器本身。 - 当我对列表进行排序时,它的迭代器会发生什么?
https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.