在迭代期间从 ArrayList 中删除多个项目
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);
正如之前的回答所说,从迭代列表中删除一个项目是不安全的。这是抛出 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");
}
如果您使用故障安全的 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 从列表中 add/remove。
在使用迭代器遍历 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);
正如之前的回答所说,从迭代列表中删除一个项目是不安全的。这是抛出 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");
}
如果您使用故障安全的 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 从列表中 add/remove。