从AbstractList(间接)继承来的子类包括:
ArrayList:
用数组来保存节点随机访问速度快,插入和移除性能较差(需要移动余下部分元素);支持null元素;有顺序;元素可以重复;线程不安全;迭代器可反向迭代可指定开始迭代器的数组下标;size(实际长度)二分之三的动态扩容
LinkedList:
用成员内部类实现了一个节点类组成链表,随机访问速度慢,插入和删除性能高(实现了头插、尾插、指定位置插入时用size一半来判断靠近方动态选择头插或尾插);支持null(Node的iterm域来保存);有顺序;元素可重复;线程不安全;迭代器可反向迭代
Vector:
和ArravList类似,但是他是线程安全的。用数组来保存节点,随机访问快,插入删除慢(需要移动余下部分元素);支持null元素,元素可重复,线程安全,迭代器可反向迭代可以指定开始迭代的数组下标;实际长度的两倍扩容
1.ArrayList
首先继承自AbstractList,并实现了相关接口,源码如下:
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{ }
两个重要的成员,其他省略,源码如下:
//工作用的数组 transient Object[] elementData; //集合大小 private int size;
重要的构造函数,源码如下:
//通过集合创建数组 public ArrayList(Collection<? extends E> c) { //调用集合自己的toArray转为数组,elementData指向他 elementData = c.toArray(); if ((size = elementData.length) != 0) { //c.toArray()方法可能调用错误而不返回Object数组,这里利用copyOf强制生成数组 if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } else { this.elementData = EMPTY_ELEMENTDATA; } }
部分普通方法,源码如下:
//确保size=elementData.length。去掉elementData数组动态增长过程中的多余容量 public void trimToSize() { //此方法调用会造成modCount值更改(可能引起迭代器快速失败) modCount++; if (size < elementData.length) { //截取,去掉动态增长产生的多余容量 elementData = (size == 0)? EMPTY_ELEMENTDATA: Arrays.copyOf(elementData, size); } } //下标超过size抛出数组越界异常 private void rangeCheck(int index) { if (index >= size)throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } //下标超过size抛出数组越界异常 private void rangeCheckForAdd(int index) { if (index > size || index < 0) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } //克隆 public Object clone() { try { //浅克隆仅克隆ArrayList对象本身 ArrayList<?> v = (ArrayList<?>) super.clone(); //赋值其引用对象elementData v.elementData = Arrays.copyOf(elementData, size); v.modCount = 0; return v; } catch (CloneNotSupportedException e) { throw new InternalError(e); } } @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { 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; } private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ int expectedModCount = modCount; s.defaultWriteObject(); s.writeInt(size); for (int i=0; i<size; i++) { s.writeObject(elementData[i]); } if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } } private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { elementData = EMPTY_ELEMENTDATA; s.defaultReadObject(); s.readInt(); if (size > 0) { ensureCapacityInternal(size); Object[] a = elementData; for (int i=0; i<size; i++) { a[i] = s.readObject(); } } }
扩容函数,实现自动容量增长的方法实现,以原来容量一半的增长方式,源码如下:
//数组扩容 //minCapacity即实际需要的容量 private void grow(int minCapacity) { int oldCapacity = elementData.length; //右移n位相当于除以2的n次方,这里增长为原来的二分之三 int newCapacity = oldCapacity + (oldCapacity >> 1); //如果计算得到的新容量比用户输入的容量小 if (newCapacity - minCapacity < 0) //则新容量=用户输入的容量(这是为了满足用户) newCapacity = minCapacity; //如果计算得到的新容量过大 if (newCapacity - MAX_ARRAY_SIZE > 0) //容量扩展至最大(同时必须满足用户的期望容量) newCapacity = hugeCapacity(minCapacity); //截断,返回新数组 elementData = Arrays.copyOf(elementData, newCapacity); } private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; //将容量扩展到最大 private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) throw new OutOfMemoryError(); //扩展到Integer.MAX_VALUE或者Integer.MAX_VALUE-8 return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE; }
用户指定实际需要容量,调用扩容函数,复制并返回容量增长后的数组,源码如下:
//用户手动设置ArrayList容量 //minCapacity是实际需要的容量值 public void ensureCapacity(int minCapacity) { int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)? 0: DEFAULT_CAPACITY; if (minCapacity > minExpand) { ensureExplicitCapacity(minCapacity); } } //此方法判断是否需要扩容 //minCapacity是实际需要的容量 private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); } //扩容 private void ensureExplicitCapacity(int minCapacity) { modCount++; if (minCapacity - elementData.length > 0) //数组扩容 grow(minCapacity); }
元素添加函数,单个或批量、指定位置或不指定。添加函数会进行是否需要扩容检查、添加位置后面所有元素后移等操作,源码如下:
//自动顺序添加(此时实际size是小于数组长度的) public boolean add(E e) { //此方法调用会造成modCount增长 ensureCapacityInternal(size + 1); elementData[size++] = e; return true; } //指定位置添加 public void add(int index, E element) { //检查添加位置是否合法 rangeCheckForAdd(index); //此方法调用会造成modCount增长 ensureCapacityInternal(size + 1); //在index处添加一个新元素,index开始所有元素均后移一位 System.arraycopy(elementData, index, elementData, index + 1,size - index); elementData[index] = element; size++; } public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); int numNew = a.length; //判断是否需要扩容 ensureCapacityInternal(size + numNew); System.arraycopy(a, 0, elementData, size, numNew); size += numNew; return numNew != 0; } public boolean addAll(int index, Collection<? extends E> c) { rangeCheckForAdd(index); Object[] a = c.toArray(); int numNew = a.length; ensureCapacityInternal(size + numNew); // Increments modCount int numMoved = size - index; if (numMoved > 0) System.arraycopy(elementData, index, elementData, index + numNew,numMoved); System.arraycopy(a, 0, elementData, index, numNew); size += numNew; return numNew != 0; }
元素判断函数,比如获取元素下标,判断是否包含等操作,源码如下:
public int indexOf(Object o) { //元素可以为null,返回第一个null的下标 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) { //元素可以为null,返回最后一个null的下标 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; } public boolean contains(Object o) { return indexOf(o) >= 0; } @SuppressWarnings("unchecked") E elementData(int index) { return (E) elementData[index]; } public E get(int index) { rangeCheck(index); return elementData(index); } public E set(int index, E element) { rangeCheck(index); E oldValue = elementData(index); elementData[index] = element; return oldValue; }
元素删除函数,一系列的romove函数,包括移位、置null等操作,源码如下:
//根据下标删除(返回被删除元素) public E remove(int index) { rangeCheck(index); modCount++; E oldValue = elementData(index); int numMoved = size - index - 1; if (numMoved > 0) //直接index位置后的元素全部前移 System.arraycopy(elementData, index+1, elementData, index,numMoved); elementData[--size] = null; return oldValue; } //根据下标删除(不返回被删除元素) private void fastRemove(int index) { modCount++; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index,numMoved); elementData[--size] = null; } //根据元素删除 public boolean remove(Object o) { if (o == null) { //删除第一个出现的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; } //清空 public void clear() { modCount++; //所有元素置null,交给GC处理 for (int i = 0; i < size; i++) elementData[i] = null; size = 0; } //按照范围删除 protected void removeRange(int fromIndex, int toIndex) { modCount++; int numMoved = size - toIndex; //将被删除块的右边全部向左移,填充掉被删除块的位置 System.arraycopy(elementData, toIndex, elementData, fromIndex, numMoved); //没被填充的位置全部置null int newSize = size - (toIndex-fromIndex); for (int i = newSize; i < size; i++) { elementData[i] = null; } size = newSize; } //移除目标集合中‘(不)包含集合c中元素’的所有元素 //(不)包含以complement指定 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) elementData[w++] = elementData[r]; } finally { // Preserve behavioral compatibility with AbstractCollection, // even if c.contains() throws. if (r != size) { System.arraycopy(elementData, r, elementData, w, size - r); w += size - r; } if (w != size) { // clear to let GC do its work for (int i = w; i < size; i++) elementData[i] = null; modCount += size - w; size = w; modified = true; } } return modified; } //移除目标集合中含有‘集合c中元素’的所有元素 public boolean removeAll(Collection<?> c) { Objects.requireNonNull(c); return batchRemove(c, false); } //移除目标集合中‘不包含集合c中元素’的所有元素 public boolean retainAll(Collection<?> c) { Objects.requireNonNull(c); return batchRemove(c, true); }
接下来分析其迭代器,ArrayList如同父类AbstractList一样,申明了两个内部类迭代器实现,分别是简单迭代器和支持反向遍历的迭代器。首先是继承Iterator接口的iterator(),返回一个简单迭代器的非静态成员内部类实例,当然他功能有限,源码如下:
//返回简单迭代器(Iterator接口方法) public Iterator<E> iterator() { return new Itr(); } //简单迭代器 private class Itr implements Iterator<E> { //保存下一个next()方法将要访问的元素下标 int cursor; //返回当前访问的元素的下标 int lastRet = -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(); } } @Override @SuppressWarnings("unchecked") public void forEachRemaining(Consumer<? super E> consumer) { Objects.requireNonNull(consumer); final int size = ArrayList.this.size; int i = cursor; if (i >= size) { return; } final Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) { throw new ConcurrentModificationException(); } while (i != size && modCount == expectedModCount) { consumer.accept((E) elementData[i++]); } // update once at end of iteration to reduce heap write traffic cursor = i; lastRet = i - 1; checkForComodification(); } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }
还包含另一个功能更强大的迭代器,用List接口的listIterator(index)和listIterator()方法返回这个非静态成员内部类迭代器实例,这个迭代器支持反向遍历,源码如下:
//返回从指定位置开始的迭代器(List接口方法) public ListIterator<E> listIterator(int index) { if (index < 0 || index > size) throw new IndexOutOfBoundsException("Index: "+index); return new ListItr(index); } //返回迭代器(List接口方法) public ListIterator<E> listIterator() { return new ListItr(0); } private class ListItr extends Itr implements ListIterator<E> { 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(); } } }
ArrayList类的剩余部分就是对子集合的支持了,提供了subList(index,index)来获取子集合。子集合是一个非静态成员内部类实现,继承了AbstractList,有自己的元素操作方法,也有自己的迭代器,子集元素全部是在ArrayList的数组上操作的并没有创建新的数组对象。源码如下:
//子集合 private class SubList extends AbstractList<E> implements RandomAccess { //子集合的元素是在ArrayList的elementData上操作的,并没有新建数组 private final AbstractList<E> parent; //偏移 private final int parentOffset; private final int offset; int size; SubList(AbstractList<E> parent, int offset, int fromIndex, int toIndex) { this.parent = parent; this.parentOffset = fromIndex; this.offset = offset + fromIndex; this.size = toIndex - fromIndex; this.modCount = ArrayList.this.modCount; } public E set(int index, E e) { rangeCheck(index); checkForComodification(); E oldValue = ArrayList.this.elementData(offset + index); ArrayList.this.elementData[offset + index] = e; return oldValue; } public E get(int index) { rangeCheck(index); checkForComodification(); return ArrayList.this.elementData(offset + index); } public int size() { checkForComodification(); return this.size; } public void add(int index, E e) { rangeCheckForAdd(index); checkForComodification(); parent.add(parentOffset + index, e); this.modCount = parent.modCount; this.size++; } public E remove(int index) { rangeCheck(index); checkForComodification(); E result = parent.remove(parentOffset + index); this.modCount = parent.modCount; this.size--; return result; } protected void removeRange(int fromIndex, int toIndex) { checkForComodification(); parent.removeRange(parentOffset + fromIndex, parentOffset + toIndex); this.modCount = parent.modCount; this.size -= toIndex - fromIndex; } public boolean addAll(Collection<? extends E> c) { return addAll(this.size, c); } public boolean addAll(int index, Collection<? extends E> c) { rangeCheckForAdd(index); int cSize = c.size(); if (cSize==0) return false; checkForComodification(); parent.addAll(parentOffset + index, c); this.modCount = parent.modCount; this.size += cSize; return true; } public Iterator<E> iterator() { return listIterator(); } //子集合listIterator方法直接返回一个ListIterator<E>匿名实现类 public ListIterator<E> listIterator(final int index) { checkForComodification(); rangeCheckForAdd(index); final int offset = this.offset; return new ListIterator<E>() { int cursor = index; int lastRet = -1; int expectedModCount = ArrayList.this.modCount; public boolean hasNext() { return cursor != SubList.this.size; } @SuppressWarnings("unchecked") public E next() { checkForComodification(); int i = cursor; if (i >= SubList.this.size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (offset + i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[offset + (lastRet = i)]; } public boolean hasPrevious() { return cursor != 0; } @SuppressWarnings("unchecked") public E previous() { checkForComodification(); int i = cursor - 1; if (i < 0) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (offset + i >= elementData.length) throw new ConcurrentModificationException(); cursor = i; return (E) elementData[offset + (lastRet = i)]; } @SuppressWarnings("unchecked") public void forEachRemaining(Consumer<? super E> consumer) { Objects.requireNonNull(consumer); final int size = SubList.this.size; int i = cursor; if (i >= size) { return; } final Object[] elementData = ArrayList.this.elementData; if (offset + i >= elementData.length) { throw new ConcurrentModificationException(); } while (i != size && modCount == expectedModCount) { consumer.accept((E) elementData[offset + (i++)]); } // update once at end of iteration to reduce heap write traffic lastRet = cursor = i; checkForComodification(); } public int nextIndex() { return cursor; } public int previousIndex() { return cursor - 1; } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { SubList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = ArrayList.this.modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } public void set(E e) { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.set(offset + lastRet, e); } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } public void add(E e) { checkForComodification(); try { int i = cursor; SubList.this.add(i, e); cursor = i + 1; lastRet = -1; expectedModCount = ArrayList.this.modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (expectedModCount != ArrayList.this.modCount) throw new ConcurrentModificationException(); } }; } public List<E> subList(int fromIndex, int toIndex) { subListRangeCheck(fromIndex, toIndex, size); return new SubList(this, offset, fromIndex, toIndex); }
2.LinkedList
AbstractList子类LinkedList比较简单,除了继承并重写了父类的特性之外,基本就是申明静态成员内部类来表示节点Node<E>,且节点的增删改查和任何一本数据结构书上的链表实现几乎一样。
首先继承了AbstractSequentialList类,并实现了相关接口,他的父类方法基本已经被他覆盖。类申明源码如下:
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable { }
包含的主要成员就是头结点、尾结点的引用和元素size。源码如下:
transient int size = 0; transient Node<E> first; transient Node<E> last; public LinkedList() { } public LinkedList(Collection<? extends E> c) { this(); addAll(c); }
最重要的是自己实现了整个链表数据结构,包括节点定义和节点基本的添加、删除方法。直接申明了一个静态成员内部类Node<E>。源码如下:
//节点定义 //由于定义了节点,所以节点iterm域可以为空,使得LinkedList可以保存null private static class Node<E> { E item;//当前节点的对象 Node<E> next;//下个节点 Node<E> prev;//上一个节点 Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } } //返回指定位置的节点 Node<E> node(int index) { //如果位置<size的一半 if (index < (size >> 1)) { //正向遍历查找 Node<E> x = first; for (int i = 0; i < index; i++) x = x.next; return x; } else { //反向遍历查找 Node<E> x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x; } } //添加到链表尾部 void linkLast(E e) { final Node<E> l = last;//指向原来的尾部 final Node<E> newNode = new Node<>(l, e, null);//以尾部为前趋创建新节点 last = newNode;//last指向新节点,也就是新尾部 //链表为空,那么新节点既是头也是尾 if (l == null) first = newNode; //链表不为空,原来的尾部节点的next指向新节点,完成插入 else l.next = newNode; //更新size size++; modCount++; } //添加到链表头部 private void linkFirst(E e) { final Node<E> f = first; final Node<E> newNode = new Node<>(null, e, f); first = newNode; if (f == null) last = newNode; else f.prev = newNode; size++; modCount++; } //在某个节点前面添加 void linkBefore(E e, Node<E> succ) { //获取目标节点的前趋结点的引用 final Node<E> pred = succ.prev; //以目标节点作为后继创建新节点 final Node<E> newNode = new Node<>(pred, e, succ); //目标节点前趋指向新节点 succ.prev = newNode; //如果目标节点没有前趋,则新节点就是first if (pred == null) first = newNode; else //目标节点的前趋结点的next指向新节点,完成插入 pred.next = newNode; size++; modCount++; } //删掉第一个节点 //传入的是第一个节点 private E unlinkFirst(Node<E> f) { final E element = f.item; //保存待删除节点的next的引用,后续作为新的first final Node<E> next = f.next; //将待删除节点的对象域置null f.item = null; //将待删除节点next域置null f.next = null; //新的first first = next; if (next == null) last = null; else //将新first的前趋置null next.prev = null; size--; modCount++; return element; } //删掉最后一个节点 private E unlinkLast(Node<E> l) { final E element = l.item; final Node<E> prev = l.prev; l.item = null; l.prev = null; last = prev; if (prev == null) first = null; else prev.next = null; size--; modCount++; return element; } //删掉一个普通节点 E unlink(Node<E> x) { final E element = x.item; final Node<E> next = x.next; final Node<E> prev = x.prev; if (prev == null) { first = next; } else { prev.next = next; x.prev = null; } if (next == null) { last = prev; } else { next.prev = prev; x.next = null; } x.item = null; size--; modCount++; return element; }
除了节点添加、删除方法的基本实现之外,LinkedList覆盖父类或者实现接口的方法基本都是基于上面方法来完成的。一系列的add、remove、get、set方法等等。源码如下:
//add //默认在最后添加 public boolean add(E e) { //这里默认添加到链表最后 linkLast(e); return true; } //在头部添加 public void addFirst(E e) { linkFirst(e); } //在尾部添加 public void addLast(E e) { linkLast(e); } //指定位置添加 public void add(int index, E element) { checkPositionIndex(index); if (index == size) linkLast(element); else linkBefore(element, node(index)); } //在尾部添加子集 public boolean addAll(Collection<? extends E> c) { return addAll(size, c); } //在指定位置添加子集 public boolean addAll(int index, Collection<? extends E> c) { checkPositionIndex(index); //先将自己转换成数组,方便遍历 Object[] a = c.toArray(); int numNew = a.length; if (numNew == 0) return false; //pred保存当前的last Node<E> pred, succ; if (index == size) { succ = null; pred = last; } else { succ = node(index); pred = succ.prev; } //遍历数组,循环创建节点,然后插入 for (Object o : a) { @SuppressWarnings("unchecked") E e = (E) o; Node<E> newNode = new Node<>(pred, e, null); if (pred == null) first = newNode; else pred.next = newNode; pred = newNode; } if (succ == null) { last = pred; } else { pred.next = succ; succ.prev = pred; } size += numNew; modCount++; return true; } //get public E getFirst() { final Node<E> f = first; if (f == null) throw new NoSuchElementException(); return f.item; } public E getLast() { final Node<E> l = last; if (l == null) throw new NoSuchElementException(); return l.item; } public E get(int index) { checkElementIndex(index); return node(index).item; } //删除第一个节点 public E removeFirst() { final Node<E> f = first; if (f == null) throw new NoSuchElementException(); return unlinkFirst(f); } //删除最后一个节点 public E removeLast() { final Node<E> l = last; if (l == null) throw new NoSuchElementException(); return unlinkLast(l); } //删除指定节点 //由于删除后直接return,所以重复的只会删除第一个 public boolean remove(Object o) { //这个null指的不是节点为null,而是节点item域为null if (o == null) { for (Node<E> x = first; x != null; x = x.next) { if (x.item == null) { unlink(x); return true; } } } else { //顺序遍历 for (Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item)) { unlink(x); return true; } } } return false; } //删除指定节点(最先一次出现) public boolean removeFirstOccurrence(Object o) { return remove(o); } //删除指定节点(最后一次出现) public boolean removeLastOccurrence(Object o) { if (o == null) { for (Node<E> x = last; x != null; x = x.prev) { if (x.item == null) { unlink(x); return true; } } } else { //倒叙遍历 for (Node<E> x = last; x != null; x = x.prev) { if (o.equals(x.item)) { unlink(x); return true; } } } return false; } //指定位置删除 public E remove(int index) { checkElementIndex(index); return unlink(node(index)); } //清空 public void clear() { //从first开始 for (Node<E> x = first; x != null; ) { //获取next节点的引用 Node<E> next = x.next; //将域置null x.item = null; x.next = null; x.prev = null; x = next; } first = last = null; size = 0; modCount++; } //获取节点index(顺序) //这里传入的是节点的iterm域 public int indexOf(Object o) { int index = 0; if (o == null) { for (Node<E> x = first; x != null; x = x.next) { if (x.item == null) return index; index++; } } else { for (Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item)) return index; index++; } } return -1; } //获取节点index(倒叙) //这里传入的是节点的iterm域 public int lastIndexOf(Object o) { int index = size; if (o == null) { for (Node<E> x = last; x != null; x = x.prev) { index--; if (x.item == null) return index; } } else { for (Node<E> x = last; x != null; x = x.prev) { index--; if (o.equals(x.item)) return index; } } return -1; } //判断是否包含节点 //传入的是节点的iterm域 public boolean contains(Object o) { return indexOf(o) != -1; } //修改结点iterm域 public E set(int index, E element) { checkElementIndex(index); Node<E> x = node(index); E oldVal = x.item; x.item = element; return oldVal; }
LinkedList剩余部分就是他的迭代器实现。他有两个迭代器且均是以成员内部类形式申明,并提供公有方法返回迭代器实例。第一个是ListIterator<E>迭代器,可双向迭代、可指定迭代器开始的位置,提供了add、set、remove方法。源码如下:
public ListIterator<E> listIterator(int index) { checkPositionIndex(index); return new ListItr(index); } //返回ListItr迭代器 //可双向遍历 //可返回从指定位置开始的迭代器 private class ListItr implements ListIterator<E> { private Node<E> lastReturned; private Node<E> next; private int nextIndex; private int expectedModCount = modCount; //指定index开始的迭代器 ListItr(int index) { next = (index == size) ? null : node(index); nextIndex = index; } public boolean hasNext() { return nextIndex < size; } //向后 public E next() { checkForComodification(); if (!hasNext()) throw new NoSuchElementException(); lastReturned = next; next = next.next; nextIndex++; return lastReturned.item; } public boolean hasPrevious() { return nextIndex > 0; } //向前 public E previous() { checkForComodification(); if (!hasPrevious()) throw new NoSuchElementException(); lastReturned = next = (next == null) ? last : next.prev; nextIndex--; return lastReturned.item; } public int nextIndex() { return nextIndex; } public int previousIndex() { return nextIndex - 1; } public void remove() { checkForComodification(); if (lastReturned == null) throw new IllegalStateException(); Node<E> lastNext = lastReturned.next; unlink(lastReturned); if (next == lastReturned) next = lastNext; else nextIndex--; lastReturned = null; expectedModCount++; } public void set(E e) { if (lastReturned == null) throw new IllegalStateException(); checkForComodification(); lastReturned.item = e; } public void add(E e) { checkForComodification(); lastReturned = null; if (next == null) linkLast(e); else linkBefore(e, next); nextIndex++; expectedModCount++; } public void forEachRemaining(Consumer<? super E> action) { Objects.requireNonNull(action); while (modCount == expectedModCount && nextIndex < size) { action.accept(next.item); lastReturned = next; next = next.next; nextIndex++; } checkForComodification(); } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }
LinkedList还包含另外一个成员内部类迭代器实现descendingIterator。这个迭代器比较简单,就是利用上面的ListItr的next()来实现自己的pervious()达到反向迭代的效果。源码如下:
//返回descendingIterator迭代器 public Iterator<E> descendingIterator() { return new DescendingIterator(); } private class DescendingIterator implements Iterator<E> { //利用ListItr迭代器进行反向操作 private final ListItr itr = new ListItr(size()); //Next()方法利用ListItr的previous()实现 public boolean hasNext() { return itr.hasPrevious(); } public E next() { return itr.previous(); } public void remove() { itr.remove(); } }
3.Vector
vector继承自AbstractList,实现了相关接口,类申明源码如下:
public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{ }
和ArrayList一样,同样使用数组来存放Object对象,同样包含三个重要成员(数组、实际长度、扩容系数)。其中扩容系数仅仅用来判断新长度是否需要翻倍。源码如下:
//使用数组保存数据 protected Object[] elementData; //实际使用长度 protected int elementCount; //扩容系数 protected int capacityIncrement;
构造函数,针对上面几个成员进行了重载。源码如下:
//构造函数相关 public Vector(int initialCapacity, int capacityIncrement) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; this.capacityIncrement = capacityIncrement; } public Vector(int initialCapacity) { this(initialCapacity, 0); } public Vector() { this(10); } public Vector(Collection<? extends E> c) { elementData = c.toArray(); elementCount = elementData.length; if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, elementCount, Object[].class); }
扩容相关函数,注意ArrarList是变为原来的1.5倍,Vector是变为原来的2倍。源码如下:
//扩容相关 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; public synchronized void ensureCapacity(int minCapacity) { if (minCapacity > 0) { modCount++; ensureCapacityHelper(minCapacity); } } private void ensureCapacityHelper(int minCapacity) { if (minCapacity - elementData.length > 0) grow(minCapacity); } //扩容 //指定必须满足的最小长度 private void grow(int minCapacity) { int oldCapacity = elementData.length; //系数小于0,新长度等于旧长度的两倍 int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity); //新长度不能满足用户指定容量,将用户指定容量设置为新长度 if (newCapacity - minCapacity < 0) newCapacity = minCapacity; //新长度比最大允许值还大,设置为最大-8 if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); elementData = Arrays.copyOf(elementData, newCapacity); } //用户指定的最小长度超过MaxValue-8,则新长度为MaxValue private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; } //外部导出方法,允许外部手动调用扩容函数 public synchronized void setSize(int newSize) { modCount++; if (newSize > elementCount) { ensureCapacityHelper(newSize); } else { for (int i = newSize ; i < elementCount ; i++) { elementData[i] = null; } } elementCount = newSize; }
重要的元素操作方法,包括插入、删除等,一部分是内部使用的工具函数一部分是公有的导出函数。由于使用了数组来保存集合,插入或者删除操作需要将目标位置后面的所有元素都移动一个位置(使用System.copyof复制数组实现的)。部分源码如下:
//元素操作方法 //就是遍历数组,删除或添加会造成后面元素移动1位(调用system.arraycopy),添加时扩容检查,线程同步, public synchronized void trimToSize() { modCount++; int oldCapacity = elementData.length; if (elementCount < oldCapacity) { elementData = Arrays.copyOf(elementData, elementCount); } } //查找元素下标 //从index开始往后查找 public synchronized int indexOf(Object o, int index) { //如果是null,返回数组从index开始往后的第一个null出现的下标 if (o == null) { for (int i = index ; i < elementCount ; i++) if (elementData[i]==null) return i; } //返回对象o从index开始第一次出现的下标 else { for (int i = index ; i < elementCount ; i++) if (o.equals(elementData[i])) return i; } return -1; } //查找元素下标 //从index开始往前查找 public synchronized int lastIndexOf(Object o, int index) { if (index >= elementCount) throw new IndexOutOfBoundsException(index + " >= "+ elementCount); if (o == null) { for (int i = index; i >= 0; i--) if (elementData[i]==null) return i; } else { for (int i = index; i >= 0; i--) if (o.equals(elementData[i])) return i; } return -1; } //删除指定位置的元素 //会造成后面所有节点前移一位 public synchronized void removeElementAt(int index) { modCount++; if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount); } else if (index < 0) { throw new ArrayIndexOutOfBoundsException(index); } //被删除的位置后面所有节点前移一位 int j = elementCount - index - 1; if (j > 0) { System.arraycopy(elementData, index + 1, elementData, index, j); } elementCount--; elementData[elementCount] = null; } //插入节点 //会造成插入位置后面所有元素后移一位 public synchronized void insertElementAt(E obj, int index) { modCount++; if (index > elementCount) { throw new ArrayIndexOutOfBoundsException(index + " > " + elementCount); } //扩容检查 ensureCapacityHelper(elementCount + 1); //插入位置后所有元素后移一位 System.arraycopy(elementData, index, elementData, index + 1, elementCount - index); elementData[index] = obj; elementCount++; } //外部导出方法:删除指定元素 public synchronized boolean removeElement(Object obj) { modCount++; int i = indexOf(obj); if (i >= 0) { removeElementAt(i); return true; } return false; } //删除元素 public synchronized E remove(int index) { modCount++; if (index >= elementCount) throw new ArrayIndexOutOfBoundsException(index); E oldValue = elementData(index); int numMoved = elementCount - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--elementCount] = null; // Let gc do its work return oldValue; } //批量添加,指定位置 public synchronized boolean addAll(int index, Collection<? extends E> c) { modCount++; if (index < 0 || index > elementCount) throw new ArrayIndexOutOfBoundsException(index); Object[] a = c.toArray(); int numNew = a.length; ensureCapacityHelper(elementCount + numNew); int numMoved = elementCount - index; if (numMoved > 0) System.arraycopy(elementData, index, elementData, index + numNew, numMoved); System.arraycopy(a, 0, elementData, index, numNew); elementCount += numNew; return numNew != 0; } //排序 @SuppressWarnings("unchecked") @Override public synchronized void sort(Comparator<? super E> c) { final int expectedModCount = modCount; //调用的是Arrays.sort() Arrays.sort((E[]) elementData, 0, elementCount, c); if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } modCount++; } //返回指定下标范围的子集合 public synchronized List<E> subList(int fromIndex, int toIndex) { return Collections.synchronizedList(super.subList(fromIndex, toIndex), this); }
剩下就是他的迭代器,重要的是他的ListItr可以指定开始迭代的数组下标、可以反向迭代。当然他也实现了jdk1.8给出的并行迭代器。部分源码如下:
//返回指定开始位置的迭代器 public synchronized ListIterator<E> listIterator(int index) { if (index < 0 || index > elementCount) throw new IndexOutOfBoundsException("Index: "+index); return new ListItr(index); } //返回整个迭代器 public synchronized ListIterator<E> listIterator() { return new ListItr(0); } //返回普通迭代器 public synchronized Iterator<E> iterator() { return new Itr(); } //普通迭代器实现类 private class Itr implements Iterator<E> { //下一次next()将要访问的元素的下标 int cursor; //本次被访问元素的下标,此元素可能会被删除掉 int lastRet = -1; int expectedModCount = modCount; public boolean hasNext() { return cursor != elementCount; } public E next() { synchronized (Vector.this) { checkForComodification(); int i = cursor; if (i >= elementCount) throw new NoSuchElementException(); cursor = i + 1; return elementData(lastRet = i); } } public void remove() { if (lastRet == -1) throw new IllegalStateException(); synchronized (Vector.this) { checkForComodification(); Vector.this.remove(lastRet); expectedModCount = modCount; } cursor = lastRet; lastRet = -1; } @Override public void forEachRemaining(Consumer<? super E> action) { Objects.requireNonNull(action); synchronized (Vector.this) { final int size = elementCount; int i = cursor; if (i >= size) { return; } @SuppressWarnings("unchecked") final E[] elementData = (E[]) Vector.this.elementData; if (i >= elementData.length) { throw new ConcurrentModificationException(); } while (i != size && modCount == expectedModCount) { action.accept(elementData[i++]); } cursor = i; lastRet = i - 1; checkForComodification(); } } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } } //list迭代器实现类,主要是可以指定下标开始迭代,可以反向迭代 final class ListItr extends Itr implements ListIterator<E> { ListItr(int index) { super(); cursor = index; } public boolean hasPrevious() { return cursor != 0; } public int nextIndex() { return cursor; } public int previousIndex() { return cursor - 1; } public E previous() { synchronized (Vector.this) { checkForComodification(); int i = cursor - 1; if (i < 0) throw new NoSuchElementException(); cursor = i; return elementData(lastRet = i); } } public void set(E e) { if (lastRet == -1) throw new IllegalStateException(); synchronized (Vector.this) { checkForComodification(); Vector.this.set(lastRet, e); } } public void add(E e) { int i = cursor; synchronized (Vector.this) { checkForComodification(); Vector.this.add(i, e); expectedModCount = modCount; } cursor = i + 1; lastRet = -1; } }