——每天的寥寥几笔,坚持下去,将会是一份沉甸甸的积累。
了解了上一篇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中的底层函数。
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; }
----迭代器----
两个方法返回两个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接口,该接口会告知虚拟机对该数据类型进行随机访问查找,看看查找效率是否高效,不高效会报错。