Java集合框架源码解读(1)ArrayList

时间:2022-06-27 19:26:16

第一篇博文,从零开始记录学习Java的点点滴滴。


ArrayList中的一部分方法的解读:

indexOf()方法从前遍历elementData数组。

    public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
lastIndexOf()方法从后遍历elementData数组。
    public int lastIndexOf(Object o) {
if (o == null) {
for (int i = size-1; i >= 0; i--)
if (elementData[i]==null)
return i;
} else {
for (int i = size-1; i >= 0; i--)
if (o.equals(elementData[i]))
return i;
}
return -1;
}

add()方法首先保证数组容量能容纳size+1个元素(通过ensureCapacityInternal()方法实现),然后在size位置插入新的元素。

    public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
在任意位置插入元素由于其后的元素需要进行数组复制,故效率较低。

    public void add(int index, E element) {
rangeCheckForAdd(index);

ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}

ArrayList中定义了内部类Itr实现Iterator接口。成员变量如下:

        int cursor;       // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;

成员方法中除了hasNext()方法以外,其他的next(), remove()方法在调用时都要调用checkForComodification()方法进行并发修改检查。

        final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}

最后,ArrayList中定义了SubList内部类,用于返回ArrayList对象的一个片段。

以下内容摘自http://www.cnblogs.com/gaojing/archive/2012/06/17/java-list-sublist-caution.html

使用java.util.List.subList时最好小心点
java.util.List中有一个subList方法,用来返回一个list的一部分的视图。

List<E> subList(int fromIndex, int toIndex);
它返回原来list的从[fromIndex, toIndex)之间这一部分的视图,之所以说是视图,是因为实际上,返回的list是靠原来的list支持的。
所以,你对原来的list和返回的list做的“非结构性修改”(non-structural changes),都会影响到彼此对方。
所谓的“非结构性修改”,是指不涉及到list的大小改变的修改。相反,结构性修改,指改变了list大小的修改。
那么,如果涉及到结构性修改会怎么样呢?
如果发生结构性修改的是返回的子list,那么原来的list的大小也会发生变化;
而如果发生结构性修改的是原来的list(不包括由于返回的子list导致的改变),那么返回的子list语义上将会是undefined。在AbstractList(ArrayList的父类)中,undefined的具体表现形式是抛出一个ConcurrentModificationException。

因此,如果你在调用了sublist返回了子list之后,如果修改了原list的大小,那么之前产生的子list将会失效,变得不可使用。