Java 2 源码解读:java.util.ArrayList
arraylist是list接口的一个可变长数组实现。实现了所有list接口的操作,并允许存储null值。除了没有进行同步,arraylist基本等同于vector。在vector中几乎对所有的方法都进行了同步,但arraylist仅对writeobject和readobject进行了同步,其它比如add(object)、remove(int)等都没有同步。
1.存储
arraylist使用一个object的数组存储元素。
private transient object elementdata[];
arraylist实现了java.io.serializable接口,这儿的transient标示这个属性不需要自动序列化。下面会在writeobject()方法中详细讲解为什么要这样作。
2.add和remove
public boolean add(object o) {
ensurecapacity(size + 1); // increments modcount!!
elementdata[size++] = o;
return true;
}
注意这儿的ensurecapacity()方法,它的作用是保证elementdata数组的长度可以容纳一个新元素。在“自动变长机制”中将详细讲解。
public object remove(int index) {
rangecheck(index);
modcount++;
object 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;
}
rangecheck()的作用是进行边界检查。由于arraylist采用一个对象数组存储元素,所以在删除一个元素时需要把后面的元素前移。删除一个元素时只是把该元素在elementdata数组中的引用置为null,具体的对象的销毁由垃圾收集器负责。
modcount的作用将在下面的“iterator()中的同步”中说明。
注:在前移时使用了system提供的一个实用方法:arraycopy(),在本例中可以看出system.arraycopy()方法可以对同一个数组进行操作,这个方法是一个native方法,如果对同一个数组进行操作时,会首先把从源部分拷贝到一个临时数组,在把临时数组的元素拷贝到目标位置。
3.自动变长机制
在实例化一个arraylist时,你可以指定一个初始容量。这个容量就是elementdata数组的初始长度。如果你使用:
arraylist list = new arraylist();
则使用缺省的容量:10。
public arraylist() {
this(10);
}
arraylist提供了四种add()方法,
public boolean add(object o)
public void add(int index, object element)
public boolean addall(collection c)
public boolean addall(int index, collection c)
在每一种add()方法中,都首先调用了一个ensurecapacity(int minicapacity)方法,这个方法保证elementdata数组的长度不小于minicapacity。arraylist的自动变长机制就是在这个方法中实现的。
public void ensurecapacity(int mincapacity) {
modcount++;
int oldcapacity = elementdata.length;
if (mincapacity > oldcapacity) {
object olddata[] = elementdata;
int newcapacity = (oldcapacity * 3)/2 + 1;
if (newcapacity < mincapacity)
newcapacity = mincapacity;
elementdata = new object[newcapacity];
system.arraycopy(olddata, 0, elementdata, 0, size);
}
}
从这个方法实现中可以看出arraylist每次扩容,都扩大到原来大小的1.5倍。
每种add()方法的实现都大同小异,下面给出add(object)方法的实现:
public boolean add(object o) {
ensurecapacity(size + 1); // increments modcount!!
elementdata[size++] = o;
return true;
}
文章整理:iocblog
版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。