第一篇博文,从零开始记录学习Java的点点滴滴。
ArrayList中的一部分方法的解读:
indexOf()方法从前遍历elementData数组。
public int indexOf(Object o) {lastIndexOf()方法从后遍历elementData数组。
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;
}
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将会失效,变得不可使用。