『壹』 java中LISt遍歷時如何remove元素
public
class
RemoveElementDemo
{
public
static
void
main(String[]
args)
{
List<String>
list
=
new
ArrayList<消裂>();
list.add("100012011");
list.add("10001201s1");
list.add("10001201s1");
//中畢解決方案:
//1.i--操作
/*for(int
i
=
0;i
<
list.size();i++){
String
b
=
list.get(i);
if(b.equals("502323232")){
list.remove(i);
i--;
}
}*/
//2.反向遍歷
/*for(int
i
=
list.size()
-
1;i
>=
0;i--){
String
b
=
list.get(i);
if(b.equals("502323232")){
list.remove(i);
}
}*/
//解決方案:調用Iterator的remove()方法安全刪除元素,避免異常
Iterator<String>
iter
=
list.iterator();
while(iter.hasNext()){
String
b
=
iter.next();
if(b.equals("100012011"賣橋芹)){
iter.remove();
}
}
for(String
b
:
list){
System.out.println(b);
}
}
}
『貳』 Java中遍歷ArrayList的過程中刪除元素操作會發生並發修改異常
首先搞清楚不是x=n-1不報錯。是因為他避開了錯誤,實際當你用倒數第2個來刪除的時候,他就已經跳出循環,不會判斷最後以為,這是為什麼呢?
我們先看看加強for循環是怎麼實現的。都知道是通過迭代實現,那麼將for寫成迭代器來看。
Iterator<Object>itr=al.iterator();
while(itr.hasNext()){
Objecto=itr.next();
System.out.println(itr.hasNext());
if("n".equals(o)){
al.remove(o);
}
}
以上就是加強for循環的真正樣子。再來透析源代碼。
al.iterator():返回一個迭代器沒什麼好說的;
itr.hasNext():通過判斷cursor(游標) != size(長度)來決定是否結束循環,cursor(游標) 初始是0 每次經過itr.next() +1;當cursor==size時 會跳出循環,這也是為什麼倒數第2個不會出錯的主要原因;
itr.next(): 看源代碼可以發現每次在next()調用後,都會先調用checkForComodification()這個方法;
checkForComodification(): 主要作用是判斷itr迭代器數據是否和list一致,
有兩個參數,
第一個modCount 集合結構變動次數,如:一開始你add調用了7次,那麼這個數就是7,
第二個expectedModCount 在調用iterator()方法時,初始化值等於modCount ,
這個方法判斷當modCount !=expectedModCount 時
拋出異常,如果你調用迭代器的remove方法,expectedModCount 會重新賦值,但是你調用的是list的remove方法,那麼modCount 就會+1 而expectedModCount 不變,這就會造成modCount !=expectedModCount;
最後,看看為什麼倒數第2個不會拋異常:
當他遍歷到「n-1」時,cursor=6,然後調用remover(o)方法,size=6,這個時候調用了itr.hasNext()判斷cursor是否等於size,前面說過,當cursor==size時,跳出循環,那麼就不會進入next(),也就不會進入checkForComodification()方法,所以不會拋出異常,說白了,也就是循環次數少了一次。
結合著源碼看,應該會比較清晰。