Java集合刪除元素ArrayList實(shí)例詳解
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)類。

編寫一段測試代碼:
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();
}
}
借助上文中提到的測試實(shí)例,可以進(jìn)行每一步的推算。
1. 調(diào)用next()方法,cursor指向0號元素,i被賦值為cursor的值,然后cursor被修改為i+1,指向了1號元素,也就是null所在的位置, lastRet被賦值為0。
2. 調(diào)用next()方法,cursor指向了1號元素,賦值給i,然后cursor又通過i+1遞增變?yōu)?,lastRet被賦值為1
3. 執(zhí)行刪除,刪除該集合lastRet上所代表的元素。刪除完成后修改cursor指針同時(shí)使得expectedModCount和modCount保持一致避免fastfail。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
相關(guān)文章
SpringCloud Zuul過濾器和谷歌Gauva實(shí)現(xiàn)限流
這篇文章主要介紹了SpringCloud Zuul過濾器和谷歌Gauva實(shí)現(xiàn)限流,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
SpringBoot整合EasyExcel實(shí)現(xiàn)大規(guī)模數(shù)據(jù)的并行導(dǎo)出與壓縮下載
在 Spring Boot 應(yīng)用中,整合 EasyExcel 實(shí)現(xiàn)并行導(dǎo)出數(shù)據(jù)并進(jìn)行 Zip 壓縮下載可以極大地提高數(shù)據(jù)處理效率和用戶體驗(yàn),文中通過代碼示例介紹的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下2024-10-10
封裝了一個(gè)Java數(shù)據(jù)庫訪問管理類
剛剛試著用JDBC,仿著原來C#的寫法寫了這段代碼,自己覺得還是挺粗糙的,還煩請路過的朋友推薦一個(gè)寫得較好較完整的相關(guān)例程以便學(xué)習(xí)。謝謝!2009-02-02
解決Feign調(diào)用的GET參數(shù)傳遞的問題
這篇文章主要介紹了解決Feign調(diào)用的GET參數(shù)傳遞的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03

