今天还是要继续看一下ArrayList,做人不能半途而废咧。
先来讲一讲ensureCapacity(int minCapacity)这个方法。
官方文档的解释是
/**
* Increases the capacity of this ArrayList instance, if
* necessary, to ensure that it can hold at least the number of elements
* specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
大意就是让你的ArrayList实例能够确保可以保存下最低的minCapacity这么多个元素。
简单来说,就是如果你当前list的capacity小于minCapacity,那么就会触发一次扩容,而扩容最低是oldCapacity的1.5倍,若minCapacity>1.5*oldCapacity,那么直接容量大小扩到minCapacity。
这个方法有一个好处,在将这个好处之前先说一说add方法
二话不说,直接上代码
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
每一次add一个元素的时候,会先判断当前数组大小+1是否会越界,如果越界则触发扩容。
聪明的人就可以想到,如果在频繁向链表插入元素的情景下,将会多次触发扩容,因为ArrayList的扩容是每次将容量扩展到原来的1.5倍+1,这样的话会导致整体性能降低,所以如果提前设置一个大概的容量值minCapacity,那么系统会一次性将实例的capacity扩到minCapacity,而不会导致频繁触发grow方法。
再来看看contains(Object o)这个方法吧
这个的代码很简单
//二话不说上代码
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
通过函数名也可以看到是查找该Object在链表中的位置,若位置大于0则代表存在。
再讲一讲ArrayList中的两种remove方法吧
其实我也不知道原来还有两种remove方法的。一脸懵逼中....
//二话不说还是上代码
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;
}
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;
}
两种方式,其实是差不多的,一个是通过下标删除,会返回对应下标上存储的对象,另外一种方法是传入一个Object o,从下标0开始遍历整个链表,删除掉第一个o。
每天看一点源代码,幸福生活每一天。