日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
JavaArrayList刪除特定元素的方法

ArrayList是最常用的一種java集合,在開發(fā)中我們常常需要從ArrayList中刪除特定元素。有幾種常用的方法:

最樸實的方法,使用下標(biāo)的方式:

 
 
  1. ArrayList al = new ArrayList();
  2. al.add("a");
  3. al.add("b");
  4. //al.add("b");
  5. //al.add("c");
  6. //al.add("d");
  7. for (int i = 0; i < al.size(); i++) {
  8. if (al.get(i) == "b") {
  9. al.remove(i);
  10. i--;
  11. }
  12. }

在代碼中,刪除元素后,需要把下標(biāo)減一。這是因為在每次刪除元素后,ArrayList會將后面部分的元素依次往上挪一個位置(就是copy),所以,下一個需要訪問的下標(biāo)還是當(dāng)前下標(biāo),所以必須得減一才能把所有元素都遍歷完

還有另外一種方式:

 
 
  1. ArrayList al = new ArrayList();
  2. al.add("a");
  3. al.add("b");
  4. al.add("b");
  5. al.add("c");
  6. al.add("d");
  7. for (String s : al) {
  8. if (s.equals("a")) {
  9. al.remove(s);
  10. }
  11. }

此處使用元素遍歷的方式,當(dāng)獲取到的當(dāng)前元素與特定元素相同時,即刪除元素。從表面上看,代碼沒有問題,可是運(yùn)行時卻報異常:

 
 
  1. Exception in thread "main" java.util.ConcurrentModificationException
  2. at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:886)
  3. at java.util.ArrayList$Itr.next(ArrayList.java:836)
  4. at com.mine.collection.TestArrayList.main(TestArrayList.java:17)

從異常堆??梢钥闯?,是ArrayList的迭代器報出的異常,說明通過元素遍歷集合時,實際上是使用迭代器進(jìn)行訪問的??蔀槭裁磿a(chǎn)生這個異常呢?打斷點(diǎn)單步調(diào)試進(jìn)去發(fā)現(xiàn),是這行代碼拋出的異常:

 
 
  1. final void checkForComodification() {
  2. if (modCount != expectedModCount)
  3. throw new ConcurrentModificationException();
  4. }

modCount是集合修改的次數(shù),當(dāng)remove元素的時候就會加1,初始值為集合的大小。迭代器每次取得下一個元素的時候,都會進(jìn)行判斷,比較集合修改的次數(shù)和期望修改的次數(shù)是否一樣,如果不一樣,則拋出異常。查看集合的remove方法:

 
 
  1. private void fastRemove(int index) {
  2. modCount++;
  3. int numMoved = size - index - 1;
  4. if (numMoved > 0)
  5. System.arraycopy(elementData, index+1, elementData, index,
  6. numMoved);
  7. elementData[--size] = null; // clear to let GC do its work
  8. }

可以看到,刪除元素時modCount已經(jīng)加一,但是expectModCount并沒有增加。所以在使用迭代器遍歷下一個元素的時候,會拋出異常。那怎么解決這個問題呢?其實使用迭代器自身的刪除方法就沒有問題了

 
 
  1. ArrayList al = new ArrayList();
  2. al.add("a");
  3. al.add("b");
  4. al.add("b");
  5. al.add("c");
  6. al.add("d");
  7. Iterator iter = al.iterator();
  8. while (iter.hasNext()) {
  9. if (iter.next().equals("a")) {
  10. iter.remove();
  11. }
  12. }

查看迭代器自身的刪除方法,果不其然,每次刪除之后都會修改expectedModCount為modCount。這樣的話就不會拋出異常

 
 
  1. public void remove() {
  2. if (lastRet < 0)
  3. throw new IllegalStateException();
  4. checkForComodification();
  5. try {
  6. ArrayList.this.remove(lastRet);
  7. cursor = lastRet;
  8. lastRet = -1;
  9. expectedModCount = modCount;
  10. } catch (IndexOutOfBoundsException ex) {
  11. throw new ConcurrentModificationException();
  12. }
  13. }

建議以后操作集合類的元素時,盡量使用迭代器。可是還有一個地方不明白,modCount和expectedModCount這兩個變量究竟是干什么用的?為什么集合在進(jìn)行操作時需要修改它?為什么迭代器在獲取下一個元素的時候需要判斷它們是否一樣?它們存在總是有道理的吧

其實從異常的類型應(yīng)該是能想到原因:ConcurrentModificationException.同時修改異常??聪旅嬉粋€例子

 
 
  1. List list = new ArrayList();
  2. // Insert some sample values.
  3. list.add("Value1");
  4. list.add("Value2");
  5. list.add("Value3");
  6. // Get two iterators.
  7. Iterator ite = list.iterator();
  8. Iterator ite2 = list.iterator();
  9. // Point to the first object of the list and then, remove it.
  10. ite.next();
  11. ite.remove();
  12. /* The second iterator tries to remove the first object as well. The object does not exist and thus, a ConcurrentModificationException is thrown. */
  13. ite2.next();
  14. ite2.remove();

同樣的,也會報出ConcurrentModificationException。


網(wǎng)站名稱:JavaArrayList刪除特定元素的方法
本文網(wǎng)址:http://www.dlmjj.cn/article/cogchis.html