本文是根據 https://blog.csdn.net/qq_32575047/article/details/78902254 的帖子進行整理的,在此感謝一下。
題目:一個ArrayList對象aList中存有若干個字符串元素,現欲遍歷該ArrayList對象,刪除其中所有值爲"abc"的字符串元素,請用代碼實現。
public class Test1 {
public static void main(String[] args) {
ArrayList<String> aList = new ArrayList<String>();
aList.add("a");
aList.add("ab");
aList.add("abc");
aList.add("abcr");
aList.add("abc");
aList.add("abcf");
aList.add("abc");
aList.add("abdc");
for(int i = 0;i < aList.size();i++){
if(aList.get(i).equals("abc")){
aList.remove(i);
}
}
System.out.println(aList);
}
}
輸出結果爲:[a, ab, abcr, abcf, abdc]
也可以使用迭代器來遍歷:
Iterator<String> iter = aList.iterator();
while(iter.hasNext()){
if(iter.next().equals("abc")){
iter.remove();
}
結果與上面相同。
現在修改一下aList , 添加一條數據“abc” , 再次執行上面的兩段代碼,看一下有什麼區別。
ArrayList<String> aList = new ArrayList<String>();
aList.add("a");
aList.add("ab");
aList.add("abc");
aList.add("abc"); //多加的一行
aList.add("abcr");
aList.add("abc");
aList.add("abcf");
aList.add("abc");
aList.add("abdc");
然後再用for循環遍歷,結果變爲:
[a, ab, abc, abcr, abcf, abdc] 發現有一個“abc”沒有被移除掉。
然而使用迭代器,答案是對的,所有的“abc”都被移除掉了。
出現這種情況的原因是什麼呢?
因爲ArrayList底層的數據結構是數組, 對於數組的特性,我們都知道, 如果刪除其中某個元素的話,那麼該元素後面的所有元素都會前移一個位置,結合這個特性,回到剛纔的for循環中,就能很好的解釋爲什麼漏刪一條“abc” 了:
for(int i = 0;i < aList.size();i++){
if(aList.get(i).equals("abc")){
aList.remove(i); //刪除第一個“abc”時,後面的元素依次遷移一個位置,也就是說第二個“abc”填充到了第一個“abc”的原位置上。但是第一個“abc” remove後,執行了i++,是“原位置”的下一個位置,處於“原位置”的第二個“abc”逃過一劫,所以在結果中會出現一條“abc”
}
可以進行如下改進:
for(int i = 0;i < aList.size();i++){
if(aList.get(i).equals("abc")){
aList.remove(i);
i--;
}
}
或者進行如下改進(ArrayList從後往前遍歷):
for(int i = aList.size() -1 ;i >= 0 ; i--){
if(aList.get(i).equals("abc")){
aList.remove(i);
}
}
而迭代器不會有這樣的問題是因爲hasNext()方法,原理是指針向後移動,每運行一次it.next(),指針向後移動一次,一個一個的遍歷。爲了避免此類問題的出現,儘量還是用迭代器比較好。