ArrayList源码(2)
程序员文章站
2022-07-14 12:05:56
...
现在接着说ArrayList的另外一个常用方法remove().
remove同样也是存在两个方法
1.
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // Let gc do its work
return oldValue;
}
第一步和add里面rangeCheckForAdd(index);
相似但是并不完全相同
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
并没有判断index<0的情况,这个为什么呢?我没有想明白运行肯定出现错误
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.ArrayList.elementData(ArrayList.java:371)
at java.util.ArrayList.remove(ArrayList.java:448)
at Test.DateTest.main(DateTest.java:21)
难道是因为肯定会报错就不用判断了??恕我才能浅薄,大家如果有知道的请告诉我一声。
之后把将要移除的数据拿出并返回,数组的长度进行改变之后执行数组复制的操作,我找了个该方法说明的博客: System.arraycopy方法的使用。最后将数组的最后一位设置为null。
2.
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
这个分两种情况传来的值是否为null,如果为null,则进行对比,是否List数组中是否有null,然后将其删除,如果不是同样是遍历List来对比。
将数据从List数组中移除的方法又是:
private void fastRemove(int index) {
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // Let gc do its work
}
这段代码在remove(index)里面都有,那为什么不写成这样呢?
public E remove(int index) {
rangeCheck(index);
E oldValue = elementData(index);
fastRemove(index);
return oldValue;
}
大家想想为什么??说出来
接下来是remove的另外两个方法:
public boolean removeAll(Collection<?> c) {
return batchRemove(c, false);
}
public boolean retainAll(Collection<?> c) {
return batchRemove(c, true);
}
全用到了batchRemove只是传的第二个参数不同。
private boolean batchRemove(Collection<?> c, boolean complement) {
final Object[] elementData = this.elementData;
int r = 0, w = 0;
boolean modified = false;
try {
for (; r < size; r++)
if (c.contains(elementData[r]) == complement)
elementData[w++] = elementData[r];
} finally {
// Preserve behavioral compatibility with AbstractCollection,
// even if c.contains() throws.
if (r != size) {
System.arraycopy(elementData, r,
elementData, w,
size - r);
w += size - r;
}
if (w != size) {
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
size = w;
modified = true;
}
}
return modified;
}
大家应该知道removeAll是将相同的都删除, 留下不相同的。retainAll是将不相同的都删除,留下相同的。
代码简单,注意他们最后再遍历一遍将空出的个数最后几个都设置为null。这个在之后大家写相关的代码时一定要注意。
remove的内容都说完了,还有一个相似的clear(),这个没有啥内容。
public void clear() {
modCount++;
// Let gc do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
上一篇: 【Java集合】2 ArrayList
下一篇: ArrayList源码分析(2)
推荐阅读
-
Codeforces Round #258 (Div. 2)Devu and Flowers 容斥原理_html/css_WEB-ITnose
-
mysql查询的1个存储过程,显示2个查询结果,如何在PHP里把2个结果显示出来
-
AMD OpenCL 大学教程(2): OpenCL概述
-
MySQL (C API)VC实例及代码下载 (1)(2)
-
PHP防止SQL注入的方法(2)
-
TCP/IP详解学习笔记(2)
-
JS密码生成与强度检测完整实例(附demo源码下载)
-
原生javascript图片自动或手动切换示例附演示源码_javascript技巧
-
【每天学点管理】——计划分解的 5W2H法则
-
Struts2 带参数的结果集