點贊在看,養成習慣。web
點贊收藏,人生輝煌。面試
點擊關注【微信搜索公衆號:編程背鍋俠】,防止迷路。編程
方法名 | 描述 |
---|---|
public E remove(int index) | 根據索引刪除元素 |
public boolean remove(Object o) | 根據元素刪除元素 |
public void clear() | 將集合清空 |
public boolean removeAll(Collection<?> c) | 刪除與給定集合中相同的元素 |
@Test
public void test_remove_index(){ ArrayList<String> list = new ArrayList<>(); list.add("洛洛01"); list.add("洛洛02"); list.add("洛洛03"); list.forEach(System.out::println); // 索引刪除 list.remove(1); list.forEach(System.out::println); } 複製代碼
public E remove(int index) {
// 校驗這個索引是否在集合中存在 rangeCheck(index); // 記錄修改的次數 modCount++; // 將index對應的元素賦值給 oldValue E oldValue = elementData(index); // 計算集合中須要移動元素個數 int numMoved = size - index - 1; // 判斷要移動的元素個數是否大於0 if (numMoved > 0) // 能進到這裏面要刪除的元素確定不在集合的最後面 // 若是須要移動元素個數大於0,就使用arrayCopy方法進行拷貝 // 注意:數據源和目標數據都是elementData System.arraycopy(elementData, index+1, elementData, index, numMoved); // 將源集合最後一個元素置爲null,儘早讓垃圾回收機制對其進行回收 elementData[--size] = null; // clear to let GC do its work // 返回被刪除的元素 return oldValue; } 複製代碼
源數組中的元素數組
System.arraycopy執行前數組中元素微信
根據索引刪除元素,返回被刪除的元素。重點關注elementData數組中元素的變化,能夠幫助理解。編輯器
@Test
public void test_remove_v(){ ArrayList<String> list = new ArrayList<>(); list.add("洛洛01"); list.add("洛洛02"); list.add("洛洛03"); list.add("洛洛04"); list.forEach(System.out::println); // 值刪除 list.remove("洛洛03"); list.forEach(System.out::println); } 複製代碼
public boolean remove(Object o) {
// 判斷要刪除的元素是否爲null if (o == null) { // 被刪除的元素爲null,遍歷這個集合 for (int index = 0; index < size; index++) // 判斷集合的元素是否爲null if (elementData[index] == null) { // 若是相等,調用fastRemove方法快速刪除 fastRemove(index); return true; } } else { // 被刪除的元素不爲空,遍歷集合 for (int index = 0; index < size; index++) // 用o對象的equals方法和集合每個元素進行比較 if (o.equals(elementData[index])) { // 若是相等,調用fastRemove方法快速刪除 fastRemove(index); return true; } } // 若是集合沒有o該元素,那麼就會返回false return false; } // 根據索引快速刪除方法 private void fastRemove(int index) { // 記錄修改的次數 modCount++; // 計算要移動元素的個數 int numMoved = size - index - 1; // 若是須要移動的個數大於0,調用arrayCopy方法進行拷貝,判斷是否是在尾部插入,大於0不是在尾部 if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); // 將集合最後一個元素置爲null,儘早被釋放 elementData[--size] = null; // clear to let GC do its work } 複製代碼
源數組中的元素 post
System.arraycopy執行前數組中元素 ui
System.arraycopy執行後數組中元素 this
根據給定的元素刪除集合中與之匹配的元素。返回值爲是否刪除成功的布爾值。
@Test
public void test_clear(){ ArrayList<String> list = new ArrayList<>(); list.add("洛洛01"); list.add("洛洛02"); list.forEach(System.out::println); list.clear(); list.forEach(System.out::println); } 複製代碼
public void clear() {
// 實際修改集合次數++ modCount++; // 遍歷集合,將集合每個索引對應位置上的元素都置爲null,儘早讓其釋放 for (int i = 0; i < size; i++) elementData[i] = null; // 集合長度更改成0 size = 0; } 複製代碼
源數組中的元素
清空之後的數組
將集合清空。這個方法會將集合每個索引對應位置上的元素都置爲null,爲的是儘早讓垃圾收集器回收。
@Test
public void test_remove_all(){ ArrayList<String> list = new ArrayList<>(); list.add("洛洛01"); list.add("洛洛02"); list.forEach(System.out::println); ArrayList<String> all = new ArrayList<>(); all.add("洛洛01"); all.add("洛洛05"); list.removeAll(all); list.forEach(System.out::println); } 複製代碼
public boolean removeAll(Collection<?> c) {
// 校驗集合是否爲空,爲空拋出空指針異常 Objects.requireNonNull(c); // 批量刪除 return batchRemove(c, false); } 複製代碼
源數組中的元素
源數組變化之後的元素
刪除與給定集合中相同的元素。這個方法的主要實現是
batchRemove
方法。
private boolean batchRemove(Collection<?> c, boolean complement) {
// 將原始數組的地址賦值給elementData final Object[] elementData = this.elementData; // r:用於遍歷原始數組,原始數組中元素的索引, w:記錄的是未被刪除元素的個數 int r = 0, w = 0; // modified:是否刪除成功給個默認值false boolean modified = false; try { // 遍歷原始數組,size爲原始數組的長度 for (; r < size; r++) // complement的給定的值爲false,判斷指定的集合c是否不包含這個元素 if (c.contains(elementData[r]) == complement) // 指定的集合c中不包含原始數組中的元素,將這個元素放到elementData數組中。 // 這個循環執行完畢,elementData數組中存放的就是從索引0開始存放未被刪除的元素,和後面可能有要被刪除的和未被刪除的元素,總的長度是原始數組的size。被刪除的元素會留在原位置,未被刪除的元素原位置有一份,還有一份複製到前面。 elementData[w++] = elementData[r]; } finally { // 正常狀況下r == size的,這個不等因而拋出了異常 if (r != size) { // 數組的拷貝,參看個人其餘文章,有這個方法的源碼詳解 System.arraycopy(elementData, r, elementData, w, size - r); // 計算修改的次數 w += size - r; } // 判斷w【記錄未被刪除的元素的個數】是否等於元素數組的長度 if (w != size) { // clear to let GC do its work,方便垃圾回收,將elementData數組從索引i=w開始,置空每一個元素 for (int i = w; i < size; i++) // 置空元素 elementData[i] = null; // size - w刪除元素的個數,modCount記錄的是修改的次數,每刪除一個元素modCount加1 modCount += size - w; // 刪除執行完之後集合的長度 size = w; // 刪除成功modified 賦值爲true modified = true; } } // 返回是否刪除成功 return modified; } 複製代碼
第一篇:ArrayList中的構造方法源碼在面試中被問到了...抱歉沒準備好!!!告辭
第二篇:面試官讓我講ArrayList中add、addAll方法的源碼...我下次再來
第三篇:工做兩年還沒看過ArrayList中remove、removeAll、clear方法源碼的都來報道吧
創做不易, 很是歡迎你們的點贊、評論和關注(^_−)☆
你的點贊、評論以及關注是對我最大的支持和鼓勵,而你的支持和鼓勵
我繼續創做高質量博客的動力 !!!