概述
1 List接口的可变数组的实现,数组默认初始化容量为10 。采用复制的方式,影响性能,尽量预估需要的容量大小:
public ArrayList(int initialCapacity);
public ArrayList(Collection<? extend E>);
2 自动增长采用拷贝的方式:
private void grow(int minCapacity){
int newCapacity=elementData.length+(elementData.length>>1);
... 判断上限和下限问题
elementData=Arrays.Copy(elementData,newCapacity);
}
自动扩容,采用复制的方式,在添加大量元素前,可以手动调用 ensureeCapacity(int minCapacity)方法扩容。
扩容过程不是线程安全的,多线程操作需要外部保证线程安全。创建同步线程的ArrayList
List list=Collections.synchronizedList(new ArrayList());
3 add函数
public boolean add(E e){
elementData[size++]=e;
//将元素加到数组最后
}
public void add(int index,E element){
System.arraycopy(elementData,index,elementData,index+1,size-index);
elementData[index]=element;
size++;
}
关于arraycopy方法:
public static native void arraycopy(Object src,int srcPos,Object dest,int destPos,int length);
native修饰符标识该方法的实现体并非java,而是c++或者其他语言,有助于提高性能。
4 序列化
transient Object[] elementData;
ArrayList需要开辟多余空间来保存数据,而序列化和反序列化这些没有存放数据的空间需要消耗更多资源,所有ArrayList数组声明为transient,并且自己实现writeObject(ObjectOutputStream o)和readObject(ObjectOutputStream o)方法。
5 modCount
向ArrayList添加、删除元素或者手动修改数组大小,会引起结构改变,导致Iterator报ConcurrentModificationException异常。
当ArrayList使用了iterator()方法产生自身对应的Iterator后,只能使用Iterator自身的remove和add方法来修改ArrayList的结构,其他修改都会引起ConcurrentModificationException异常。
6 clone()方法
实现Cloneable接口(该接口是空的),表明是可以进行浅拷贝的,可以调用Object.clone()返回该对象的浅拷贝。
浅拷贝:
(x.clone()!=x)==true,它们不是同一个对象
(x.clone().getClass()==x.getClass())==true,它们是同一类型的class
(x.equals(x.clone()))==true,逻辑上和内容上,应该是相同的。
7 补充材料
Java无法直接访问到操作系统底层,因此java使用native方法来扩展java程序的功能。实现步骤:
- 在java中声明native()方法,然后编译;
- 用javah产生一个.h文件;
- 写一个.cpp文件实现native导出方法,其中需要包含第二步才生的.h文件(其中又包含了JDK带的jni.h文件);
- 将第三步的.cpp文件编译成动态链接库文件
- 在java中使用System.loadLibrary()方法加载第四步产生的动态链接库文件,这个native()方法就可以在java中被访问了。