这是使用for循环从Java中的LinkedList查找和删除项目的有效方法,是否可能出现不一致:
for(ObjectType ob : obList) {
if(ob.getId() == id) {
obList.remove(ob);
break;
}
}
Run Code Online (Sandbox Code Playgroud)
pol*_*nts 16
其他人提到了有效点,通常这不是你如何remove从集合中的对象.但是,在这种情况下,break一旦你离开循环,它就没问题remove.
但是,如果要在a之后继续迭代remove,则需要使用迭代器.否则,您将得到一个ConcurrentModificationException或更一般的情况下未定义的行为.
所以,是的,如果你break离开了foreach你之后remove,你会没事的.
对于那些说这会因为你无法修改集合而失败的人foreach- 只有你想继续迭代才会这样.这不是这种情况,所以这条捷径很好.
ConcurrentModificationException迭代器检查并抛出A. 在这之后remove(有资格作为并发修改),你就break离开了循环.迭代器甚至没有机会检测到它.
最好是添加注释break,为什么它是绝对必要的等等,因为如果稍后修改此代码以继续在a之后迭代remove,则它将失败.
我会把这个成语看作goto(或者更确切地说,标记为break/ continue):它起初可能看起来不对,但是当明智地使用它时,它会使代码更清晰.
最好使用迭代器,并在搜索对象时通过迭代集合以删除它来使用它的remove方法.这是因为
原则上,我建议在增强版之前使用以下内容:
for(Iterator<ObjectType> it=obList.iterator(); it.hasNext(); ) {
if(it.next().getId()==id) {
it.remove();
break;
}
}
Run Code Online (Sandbox Code Playgroud)
这样,您就不会对可能在未来发生变化的基础列表做出假设.
比较代码以删除迭代器remove调用的最后一个条目(格式化Sun的):
private E remove(Entry<E> e) {
if (e == header)
throw new NoSuchElementException();
E result = e.element;
e.previous.next = e.next;
e.next.previous = e.previous;
e.next = e.previous = null;
e.element = null;
size--;
modCount++;
return result;
}
Run Code Online (Sandbox Code Playgroud)
反对删除(对象)必须做的事情:
public boolean remove(Object o) {
if (o==null) {
for (Entry<E> e = header.next; e != header; e = e.next) {
if (e.element==null) {
remove(e);
return true;
}
}
} else {
for (Entry<E> e = header.next; e != header; e = e.next) {
if (o.equals(e.element)) {
remove(e);
return true;
}
}
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
你应该使用iterator.remove():
从底层集合中移除迭代器返回的最后一个元素(可选操作).每次调用next时,只能调用一次此方法.迭代器的行为是不确定如果底层的集合被修改,迭代是在比调用此方法之外的任何方式的进步.
| 归档时间: |
|
| 查看次数: |
30047 次 |
| 最近记录: |