我在阅读源码的过程中很多时候是没有头绪的。所以为了避免大家也遇到这种状况,源码不求全求大,做到“透过实践看源码”,分块分层。
首先对ArrayList做个总体介绍:
ArrayList的底层存储结构是数组,实际上在这个类中真正保存数据的是内部定义的一个数组,自身的数据操作只是封装了数组的操作!
前面介绍了ArrayList的基本操作,创建,增加,修改,删除!
下面介绍其他的一些操作!
- 清空集合
public static void main(String[] args) {
ArrayList<String> list=new ArrayList<String>();
list.add("first");
list.add("second");
list.clear();
System.out.println("集合list是否为空?"+list.isEmpty());
}
输出结果:集合list是否为空?true
源码分析:
/**
* 清空集合
*/
public void clear() {
modCount++;
// 循环清空每个元素,并设置size=0
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
- 直接添加一个集合的所有元素
public static void main(String[] args) {
ArrayList<String> list=new ArrayList<String>();
list.add("first");
list.add("second");
ArrayList<String> list2=new ArrayList<String>();
list2.add("first2");
list2.add("second2");
list.addAll(list2);
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i)+" ");
}
}
输出结果:first second first2 second2
源码分析:
/**
* 添加一个集合,将集合c中的元素依次添加
* Collection是所以集合类的父类借口,所以可以如此声明!
* <? extends E>这是泛型的相关知识!!
*/
public boolean addAll(Collection<? extends E> c) {
//将c以数组形式返回
Object[] a = c.toArray();
int numNew = a.length;
//扩充容量
ensureCapacityInternal(size + numNew);
//复制
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
也可以指定索引位置进行添加
list.addAll(1,list2);
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i)+" ");
}
输出结果:first first2 second2 second
源码分析:
/**
* 在索引index处依次添加集合c中的元素
*/
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew);
//需要移动的元素个数,通过System.arraycopy进行复制
int numMoved = size - index;
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);
System.arraycopy(a, 0, elementData, index, numNew);
size += numNew;//修改size元素个数
return numNew != 0;
}