您好,登錄后才能下訂單哦!
Java集合刪除元素ArrayList實(shí)例詳解
AbstractCollection集合類中有一個(gè)remove方法,該方法為了適配多種不同的集合,允許刪除空的元素,看這部分代碼的時(shí)候產(chǎn)生了疑問,為什么這里直接用it.remove()就直接刪除了?
public boolean remove(Object o) { Iterator<E> it = iterator(); if (o==null) { while (it.hasNext()) { if (it.next()==null) { it.remove(); return true; } } } else { while (it.hasNext()) { if (o.equals(it.next())) { it.remove(); return true; } } } return false; }
接下來,拿ArrayList為例子,進(jìn)行說明。其繼承結(jié)構(gòu)如下圖所示。并且,ArrayList內(nèi)部有其使用的Iterator的實(shí)現(xiàn)類。
編寫一段測(cè)試代碼:
AbstractCollection<String> list = new ArrayList<>(); list.add("a"); list.add(null); list.add(null); Iterator<String> iter = list.iterator(); while(iter.hasNext()) { if(iter.next() == null) { iter.remove(); } } System.out.println(list);
關(guān)鍵點(diǎn)還是在于iter.next() == null 這一行,next的源碼如下:
public E next() { checkForComodification(); int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; }
cusor在這里表示的是遍歷時(shí)的索引,在調(diào)用next方法的時(shí)候其實(shí)cusor已經(jīng)指向了當(dāng)前元素的下一個(gè)元素,而使用lasrRet來獲取當(dāng)前的索引上的數(shù)據(jù)并將其返回。
而remove()方法中是通過lastRet的索引進(jìn)行刪除的。
public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } }
借助上文中提到的測(cè)試實(shí)例,可以進(jìn)行每一步的推算。
1. 調(diào)用next()方法,cursor指向0號(hào)元素,i被賦值為cursor的值,然后cursor被修改為i+1,指向了1號(hào)元素,也就是null所在的位置, lastRet被賦值為0。
2. 調(diào)用next()方法,cursor指向了1號(hào)元素,賦值給i,然后cursor又通過i+1遞增變?yōu)?,lastRet被賦值為1
3. 執(zhí)行刪除,刪除該集合lastRet上所代表的元素。刪除完成后修改cursor指針同時(shí)使得expectedModCount和modCount保持一致避免fastfail。
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。