——每天的寥寥几笔,坚持下去,将会是一份沉甸甸的积累。
了解了上一篇java核心之集合框架——HashMap源码分析的源码分析过程,再来看ArrayList那就是小菜一碟了。
1.内部数据结构:Object[]数组
2.一般的增删add,remove函数,就是对数组进行操作,比较简单,这里略过。
3.几个需要注意和比较不好理解的函数
首先是toArray函数
ArrayList类下面:
public Object[] toArray() {
return Arrays.copyOf(elementData, size);//返回一个大小为size,内容和elementData数组一样的数组
}
public <T> T[] toArray(T[] a) {
//必须通过下面基于反射机制写的函数,不能new Object[]b; b=a;然后return T[]b;强转失败,回报运行时异常
if (a.length < size)
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
Arrays类下面:
public static <T> T[] copyOf(T[] original, int newLength) {
return (T[]) copyOf(original, newLength, original.getClass());
}
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);//通过反射机制实现数组实例的创建
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
System类下面:
public static native void arraycopy(Object src,int srcPos,Object dest,int destPos,int length);
//原数组。原数组开始的位置,要复制到的目标数组,目标数组的开始位置,要复制的长度
//该方法是用了native关键字,调用的为C++编写的底层函数,可见其为JDK中的底层函数。
其次是r etainAll(Collection<?> c)和removeAll(Collection<?> c)
public boolean removeAll(Collection<?> c) {//保留两个集合的非公共部分
return batchRemove(c, false);
}
public boolean retainAll(Collection<?> c) {//保留两个集合的公共部分
return batchRemove(c, true);
}
private boolean batchRemove(Collection<?> c, boolean complement) {
final Object[] elementData = this.elementData;
int r = 0, w = 0;
boolean modified = false;
try {
for (; r < size; r++)
if (c.contains(elementData[r]) == complement)//complement=true,则将找到的相同元素从头开始覆盖elementData数组本身
elementData[w++] = elementData[r];
} finally {
if (r != size) {//正常情况下,for循环结束,r=size,不能于则说明有异常抛出
System.arraycopy(elementData, r,elementData, w,size - r);将r后面的数组内容复制到w后面
w += size - r;//
}
if (w != size) {//将w后面无用的赋值为null
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
size = w;
modified = true;//w != size ,表明有改动,modified被置为true
}
}
return modified;
}
4.视图类相关:迭代器和SubList
----迭代器----
两个方法返回两个Iterator对象,前者支持双向遍历,后者只支持往后遍历
public ListIterator<E> listIterator() {
return new ListItr(0);
}
public Iterator<E> iterator() {
return new Itr();
}
具体实现类:
private class Itr implements Iterator<E> {//只支持单向的next往后遍历
int cursor;
//cursor:返回下一个元素(Next操作)的索引,最大=size()-1
//“越过”哪个元素,就返回该元素下一个元素(指Next)的index
int lastRet = -1;
//lastRet:返回最近一个调用Next或者previous操作“越过”哪个元素,就返回该元素的index
//remove过后,有被置为-1
int expectedModCount = modCount;//修改次数
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
private class ListItr extends Itr implements ListIterator<E> {//支持双向遍历,next or previous
ListItr(int index) {
super();
cursor = index;
}
public boolean hasPrevious() {
return cursor != 0;
}
public int nextIndex() {
return cursor;
}
public int previousIndex() {
return cursor - 1;
}
@SuppressWarnings("unchecked")
public E previous() {
checkForComodification();
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i;
return (E) elementData[lastRet = i];
}
public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.set(lastRet, e);
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
public void add(E e) {
checkForComodification();
try {
int i = cursor;
ArrayList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}
---
SubList----
class SubList<E> extends AbstractList<E> {
//继承AbstractList,几乎把所有方法覆写了,使得subList对象拥有和arrayList对象一样的各种功能。
//代码很简单,就是重写的时候用新的索引。
private final AbstractList<E> l;
private final int offset;
private int size;
SubList(AbstractList<E> list, int fromIndex, int toIndex) {
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
if (toIndex > list.size())
throw new IndexOutOfBoundsException("toIndex = " + toIndex);
if (fromIndex > toIndex)
throw new IllegalArgumentException("fromIndex(" + fromIndex +
") > toIndex(" + toIndex + ")");
l = list;
offset = fromIndex;
size = toIndex - fromIndex;
this.modCount = l.modCount;
}
public E set(int index, E element) {
rangeCheck(index);
checkForComodification();
return l.set(index+offset, element);
}
public E get(int index) {
rangeCheck(index);
checkForComodification();
return l.get(index+offset);
}
public int size() {
checkForComodification();
return size;
}
public void add(int index, E element) {
rangeCheckForAdd(index);
checkForComodification();
l.add(index+offset, element);
this.modCount = l.modCount;
size++;
}
public E remove(int index) {
rangeCheck(index);
checkForComodification();
E result = l.remove(index+offset);
this.modCount = l.modCount;
size--;
return result;
}
protected void removeRange(int fromIndex, int toIndex) {
checkForComodification();
l.removeRange(fromIndex+offset, toIndex+offset);
this.modCount = l.modCount;
size -= (toIndex-fromIndex);
}
public boolean addAll(Collection<? extends E> c) {
return addAll(size, c);
}
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
int cSize = c.size();
if (cSize==0)
return false;
checkForComodification();
l.addAll(offset+index, c);
this.modCount = l.modCount;
size += cSize;
return true;
}
public Iterator<E> iterator() {
return listIterator();
}
public ListIterator<E> listIterator(final int index) {
checkForComodification();
rangeCheckForAdd(index);
return new ListIterator<E>() {
private final ListIterator<E> i = l.listIterator(index+offset);
public boolean hasNext() {
return nextIndex() < size;
}
public E next() {
if (hasNext())
return i.next();
else
throw new NoSuchElementException();
}
public boolean hasPrevious() {
return previousIndex() >= 0;
}
public E previous() {
if (hasPrevious())
return i.previous();
else
throw new NoSuchElementException();
}
public int nextIndex() {
return i.nextIndex() - offset;
}
public int previousIndex() {
return i.previousIndex() - offset;
}
public void remove() {
i.remove();
SubList.this.modCount = l.modCount;
size--;
}
public void set(E e) {
i.set(e);
}
public void add(E e) {
i.add(e);
SubList.this.modCount = l.modCount;
size++;
}
};
}
public List<E> subList(int fromIndex, int toIndex) {
return new SubList<>(this, fromIndex, toIndex);
}
private void rangeCheck(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private void rangeCheckForAdd(int index) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+size;
}
private void checkForComodification() {
if (this.modCount != l.modCount)
throw new ConcurrentModificationException();
}
}
5.最后知道Arraylist实现了标记接口RandomAccess接口,该接口会告知虚拟机对该数据类型进行随机访问查找,看看查找效率是否高效,不高效会报错。