点赞在看,养成习惯。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方法源码的都来报道吧
创做不易, 很是欢迎你们的点赞、评论和关注(^_−)☆
你的点赞、评论以及关注是对我最大的支持和鼓励,而你的支持和鼓励
我继续创做高质量博客的动力 !!!