通过分析源码,你会发现,一些你在工作中无法体会到的一些现象,通过源码的了解,会扩散你的思维.这一次是讲解下ArrayList的删除以及通过角标来添加元素。在查看删除方法的时候,remove方法存在两个重载的方法,一个是index一个通过值的形式,进行删除,
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; // clear to let GC do its work
return oldValue;
}
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;
}
谁的性能强弱,一眼就知道.那么我们来看下他们是怎样的一个删除元素的呢.
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 work
通过这段代码进行删除的,现在我们来剖析下这段代码的含义.int numMoved = size - index - 1;首先这段代码,是计算当前角标下后面所有的元素的大小,size当前元素实际大小,index 当前的角标 减去1就是除去自身,且计算的后面数值个数大于0这个主要是解决性能问题.(都等于0了,就没有必要再去内存中进行拷贝一遍了) 现在重点就是System.arraycopy 是一个怎样的工作流程.我们通过一些案例和画图来对其进行描述下.先描述下System.arraycopy(elementData, index+1, elementData, index, numMoved);这个方法参数,第一个是原始数据集,第二个是从哪个地方开始进行读取,在原始数据集中,第三个是拷贝到哪里的数据集new数据集,第四个是新的数据集中将原始数据集读取到的数据放到哪个位置中,第五个,拷贝几个.
下面在通过demo来演示一波
Object[]obj={"1","2","3","null","null","null","null","null","null","null"};
int index=1;//要删除的角标
int siez=3;//当前真实大小
System.out.println("处理前的数据集:"+Arrays.toString(obj));
System.arraycopy(obj,index+1,obj,index,siez-index-1);
//进行拷贝后的数据
System.out.println("拷贝后的数据集:"+Arrays.toString(obj));
//开始进行移除操作
obj[--siez]=null;
System.out.println("删除后的数据集"+Arrays.toString(obj));
执行的结果:
处理前的数据集:[1, 2, 3, null, null, null, null, null, null, null]
拷贝后的数据集:[1, 3, 3, null, null, null, null, null, null, null]
删除后的数据集[1, 3, null, null, null, null, null, null, null, null]
可以看到,跟我们在流程图中画的一样的一个情况,通过分析后,我们可以了解到,这样的拷贝元素的数据是最快捷,效率是最有效的.