ArrayList中remove方法和set(null)的区别
在分析源碼ArrayList.remove()時,偶然發現了一個疑惑的點,就是:源碼也是將最后一個對象的引用指向null(源碼:elementData[--size] =?null; // clear to let GC do its work),而使用 list.set(最大下標,null)同樣也是將對象的引用指向null,為什么輸出的結果為:remove()方法 對應位置的值會被“刪除”,set()方法 下標位置的值依然被保留、輸出。這是為什么呢?
首先我們先看一下remove()方法的源碼,這里只講通過下標刪除。
/*** Removes the element at the specified position in this list.* Shifts any subsequent elements to the left (subtracts one from their* indices).** @param index the index of the element to be removed* @return the element that was removed from the list* @throws IndexOutOfBoundsException {@inheritDoc}*/public E remove(int index) {// 檢查下標是否越界 rangeCheck(index);// 記錄修改次數,這里就是foreach、Iterator遍歷時不能執行刪除的根本原因modCount++;E oldValue = elementData(index);int numMoved = size - index - 1;if (numMoved > 0)// 系統內置的數據復制,淺復制。什么是淺復制這里就不做擴展了System.arraycopy(elementData, index+1, elementData, index,numMoved);// 重點來了,本次探討的問題elementData[--size] = null; // clear to let GC do its workreturn oldValue;}這里我準備了一個事例用來分析,如下:
@Testpublic void Test1() {String[] array = {"1111","2222","3333","4444","5555"};List<String> setList = new ArrayList<>(Arrays.asList(array));List<String> removeList = new ArrayList<>(setList);setList.set(4, null);removeList.remove(4);System.out.println(setList);System.out.println(removeList);}輸入結果:
通過分析查找資料,終于發現了問題出在哪了,原來源碼中的?--size?就是造成兩種結果的原因,下面給出解析:
1:首先要明白一個道理,數據存儲在內存中是連續的。
其次,集合在 AbstractCollection 重寫了toString方法,可以看到 arrayList 是通過迭代器遍歷輸出的。
2:ArrayList實現了??iterator()? 方法,返回一個實現??Iterator<E>? 的內部類 ?Itr?,其中??hasNext()? 方法 決定了只返回size大小的數據,而size 正是arrayList的大小。
?
現在,知道為什么輸出的結果會是上面看到的樣子了吧。其實,上面兩種方式生成的數組,存儲在內存中是一樣的,都是最后一個對象的引用指向null,只是 remove()方法 改變了記錄數組的size大小。
?
轉載于:https://www.cnblogs.com/pan1042/p/11271118.html
總結
以上是生活随笔為你收集整理的ArrayList中remove方法和set(null)的区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: v-show与v-if的区别
- 下一篇: vue项目打包之后原本好的样式变得不好了