privatevoidgrow(int minCapacity){ // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); }
public E remove(int index){ rangeCheck(index);//判断是否越界 modCount++;//修改modeCount 因为结构改变了 E oldValue = elementData(index);//读出要删除的值 int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved);//用复制 覆盖数组数据 elementData[--size] = null; // clear to let GC do its work //置空原尾部数据 不再强引用, 可以GC掉 return oldValue; } //根据下标从数组取值 并强转 E elementData(int index){ return (E) elementData[index]; }
//删除该元素在数组中第一次出现的位置上的数据。 如果有该元素返回true,如果false。 publicbooleanremove(Object o){ if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index);//根据index删除元素 returntrue; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); returntrue; } } returnfalse; } //不会越界 不用判断 ,也不需要取出该元素。 privatevoidfastRemove(int index){ modCount++;//修改modCount int numMoved = size - index - 1;//计算要移动的元素数量 if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved);//以复制覆盖元素 完成删除 elementData[--size] = null; // clear to let GC do its work //置空 不再强引用 }
//批量删除 publicbooleanremoveAll(Collection<?> c){ Objects.requireNonNull(c);//判空 return batchRemove(c, false); } //批量移动 privatebooleanbatchRemove(Collection<?> c, boolean complement){ final Object[] elementData = this.elementData; int r = 0, w = 0;//w 代表批量删除后 数组还剩多少元素 boolean modified = false; try { //高效的保存两个集合公有元素的算法 for (; r < size; r++) if (c.contains(elementData[r]) == complement) // 如果 c里不包含当前下标元素, elementData[w++] = elementData[r];//则保留 } finally { // Preserve behavioral compatibility with AbstractCollection, // even if c.contains() throws. if (r != size) { //出现异常会导致 r !=size , 则将出现异常处后面的数据全部复制覆盖到数组里。 System.arraycopy(elementData, r, elementData, w, size - r); w += size - r;//修改 w数量 } if (w != size) {//置空数组后面的元素 // clear to let GC do its work for (int i = w; i < size; i++) elementData[i] = null; modCount += size - w;//修改modCount size = w;// 修改size modified = true; } } return modified; }
//普通的for循环寻找值,只不过会根据目标对象是否为null分别循环查找。 publicbooleancontains(Object o){ return indexOf(o) >= 0; } //普通的for循环寻找值,只不过会根据目标对象是否为null分别循环查找。 publicintindexOf(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; }
public Iterator<E> iterator(){ returnnew Itr(); } /** * An optimized version of AbstractList.Itr */ privateclassItrimplementsIterator<E> { int cursor; // index of next element to return //默认是0 int lastRet = -1; // index of last element returned; -1 if no such //上一次返回的元素 (删除的标志位) int expectedModCount = modCount; //用于判断集合是否修改过结构的 标志
@SuppressWarnings("unchecked") public E next(){ checkForComodification(); int i = cursor; if (i >= size)//判断是否越界 thrownew NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length)//再次判断是否越界,在 我们这里的操作时,有异步线程修改了List thrownew ConcurrentModificationException(); cursor = i + 1;//游标+1 return (E) elementData[lastRet = i];//返回元素 ,并设置上一次返回的元素的下标 }
publicvoidremove(){//remove 掉 上一次next的元素 if (lastRet < 0)//先判断是否next过 thrownew IllegalStateException(); checkForComodification();//判断是否修改过
//last节点插入新元素:addLast()调用 voidlinkLast(E e){ //将尾结点赋值个体L: final java.util.LinkedList.Node<E> l = last; //创建新的结点,将新节点的前指针指向l: final java.util.LinkedList.Node<E> newNode = new java.util.LinkedList.Node<>(l, e, null); //新节点置为尾结点: last = newNode; //如果尾结点l为null:则是空集合新插入 if (l == null) //头结点也置为 新节点: first = newNode; else //l节点的后指针指向新节点: l.next = newNode; //长度+1 size++; //操作数+1 modCount++; }
//向对应角标添加元素: publicvoidadd(int index, E element){ //检查传入的角标 是否正确: checkPositionIndex(index); //如果插入角标==集合长度,则插入到集合的最后面: if (index == size) linkLast(element); else //插入到对应角标的位置:获取此角标下的元素先 linkBefore(element, node(index)); } //在succ前插入 新元素e: voidlinkBefore(E e, java.util.LinkedList.Node<E> succ){ //获取被插入元素succ的前指针元素: final java.util.LinkedList.Node<E> pred = succ.prev; //创建新增元素节点,前指针 和 后指针分别指向对应元素: final java.util.LinkedList.Node<E> newNode = new java.util.LinkedList.Node<>(pred, e, succ); succ.prev = newNode; //succ的前指针元素可能为null,为null的话说明succ是头结点,则把新建立的结点置为头结点: if (pred == null) first = newNode; else //succ前指针不为null,则将前指针的结点的后指针指向新节点: pred.next = newNode; //长度+1 size++; //操作数+1 modCount++; } //移除首个结点:如果集合还没有元素则报错 public E removeFirst(){ final java.util.LinkedList.Node<E> f = first; //首节点为null,则抛出异常; if (f == null) thrownew NoSuchElementException(); return unlinkFirst(f); }
//删除LinkedList的头结点:removeFirst()方法调用 private E unlinkFirst(java.util.LinkedList.Node<E> f){ //f为头结点:获取头结点元素E final E element = f.item; //获取头结点的尾指针结点: final java.util.LinkedList.Node<E> next = f.next; //将头结点元素置为null: f.item = null; //头结点尾指针置为null: f.next = null; //将头结点的尾指针指向的结点next置为first first = next; //尾指针指向结点next为null的话,就将尾结点也置为null(LinkedList中只有一个元素时出现) if (next == null) last = null; else //将尾指针指向结点next的 前指针置为null; next.prev = null; // 长度减1 size--; //操作数+1 modCount++; //返回被删除的元素: return element; }
//移除最后一个结点:如果集合还没有元素则报错 public E removeLast(){ //获取最后一个结点: final java.util.LinkedList.Node<E> l = last; if (l == null) thrownew NoSuchElementException(); //删除尾结点: return unlinkLast(l); } //删除LinkedList的尾结点:removeLast()方法调用 private E unlinkLast(java.util.LinkedList.Node<E> l){ final E element = l.item; final java.util.LinkedList.Node<E> prev = l.prev; l.item = null; l.prev = null; // help GC last = prev; if (prev == null) first = null; else prev.next = null; size--; modCount++; return element; }
//删除LinkedList中的元素,可以删除为null的元素,逐个遍历LinkedList的元素; //重复元素只删除第一个: publicbooleanremove(Object o){ //如果删除元素为null: if (o == null) { for (java.util.LinkedList.Node<E> x = first; x != null; x = x.next) { if (x.item == null) { unlink(x); returntrue; } } } else { //如果删除元素不为null: for (java.util.LinkedList.Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item)) { unlink(x); returntrue; } } } returnfalse; } //移除LinkedList结点:remove()方法中调用 E unlink(java.util.LinkedList.Node<E> x){ //获取被删除结点的元素E: final E element = x.item; //获取被删除元素的后指针结点: final java.util.LinkedList.Node<E> next = x.next; //获取被删除元素的前指针结点: final java.util.LinkedList.Node<E> prev = x.prev;
//得到首个结点:集合没有元素报错 public E getFirst(){ //获取first结点: final java.util.LinkedList.Node<E> f = first; if (f == null) thrownew NoSuchElementException(); return f.item; }
//得到最后一个结点:集合没有元素报错 public E getLast(){ //获取last结点: final java.util.LinkedList.Node<E> l = last; if (l == null) thrownew NoSuchElementException(); return l.item; }
//添加集合:从最后size所在的index开始: publicbooleanaddAll(Collection<? extends E> c){ return addAll(size, c); } //LinkedList添加集合: publicbooleanaddAll(int index, Collection<? extends E> c){ //检查角标是否正确: checkPositionIndex(index); Object[] a = c.toArray(); int numNew = a.length; if (numNew == 0) returnfalse; java.util.LinkedList.Node<E> pred, succ; if (index == size) { succ = null; pred = last; } else { succ = node(index); pred = succ.prev; } for (Object o : a) { E e = (E) o; java.util.LinkedList.Node<E> newNode = new java.util.LinkedList.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++; returntrue; }
//清空LinkedList: publicvoidclear(){ //遍历LinedList集合: for (java.util.LinkedList.Node<E> x = first; x != null; ) { //将每个结点的前指针 尾指针 元素都置为null: java.util.LinkedList.Node<E> next = x.next; x.item = null; x.next = null; x.prev = null; x = next; } //头尾结点 都置为null: first = last = null; //长度置为0 size = 0; //操作数+1: modCount++; }
//获取相应角标的元素: public E get(int index){ //检查角标是否正确: checkElementIndex(index); //获取角标所属结点的 元素值: return node(index).item; }
//设置对应角标的元素: public E set(int index, E element){ checkElementIndex(index); java.util.LinkedList.Node<E> x = node(index); E oldVal = x.item; x.item = element; return oldVal; }
//删除对应角标的元素: public E remove(int index){ checkElementIndex(index); return unlink(node(index)); }
//获取对应角标所属于的结点: java.util.LinkedList.Node<E> node(int index){ //位运算:如果位置索引小于列表长度的一半,从前面开始遍历;否则,从后面开始遍历; if (index < (size >> 1)) { java.util.LinkedList.Node<E> x = first; //从头结点开始遍历:遍历的长度就是index的长度,获取对应的index的元素 for (int i = 0; i < index; i++) x = x.next; return x; } else { //从集合尾结点遍历: java.util.LinkedList.Node<E> x = last; //同样道理: for (int i = size - 1; i > index; i--) x = x.prev; return x; } } // 左移相当于*2,只是要注意边界问题。如char a = 65; a<<1 按照*2来算为130; // 但有符号char的取值范围-128~127,已经越界,多超出了3个数值, // 所以从-128算起的第三个数值-126才是a<<1的正确结果。 //而右移相当于除以2,只是要注意移位比较多的时候结果会趋近去一个非常小的数,如上面结果中的-1,0。
privatebooleanisElementIndex(int index){ return index >= 0 && index < size; }
//判断传入的index是否正确: privatebooleanisPositionIndex(int index){ return index >= 0 && index <= size; }
privatevoidcheckElementIndex(int index){ if (!isElementIndex(index)) thrownew IndexOutOfBoundsException(outOfBoundsMsg(index)); }
//检查传入的角标 是否正确: privatevoidcheckPositionIndex(int index){ //必须大于0 ,并且不能大于当前size: if (!isPositionIndex(index)) thrownew IndexOutOfBoundsException(outOfBoundsMsg(index)); } publicintindexOf(Object o){ int index = 0; if (o == null) { for (java.util.LinkedList.Node<E> x = first; x != null; x = x.next) { if (x.item == null) return index; index++; } } else { for (java.util.LinkedList.Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item)) return index; index++; } } return -1; } publicintlastIndexOf(Object o){ int index = size; if (o == null) { for (java.util.LinkedList.Node<E> x = last; x != null; x = x.prev) { index--; if (x.item == null) return index; } } else { for (java.util.LinkedList.Node<E> x = last; x != null; x = x.prev) { index--; if (o.equals(x.item)) return index; } } return -1; }
//获取第一个元素,不存在则抛异常 public E element(){ return getFirst(); }
//出队,获取第一个元素,不出队列,只是获取 // 队列先进先出;不存在不抛异常,返回null public E peek(){ //获取头结点: final java.util.LinkedList.Node<E> f = first; //存在获取头结点元素,不存在返回null return (f == null) ? null : f.item; }
//出队,并移除第一个元素;不存在不抛异常。 public E poll(){ final java.util.LinkedList.Node<E> f = first; return (f == null) ? null : unlinkFirst(f); }
//出队(删除第一个结点),如果不存在会抛出异常而不是返回null,存在的话会返回值并移除这个元素(节点) public E remove(){ return removeFirst(); }
//出队(从前端),获得第一个元素,不存在会返回null,不会删除元素(节点) public E peekFirst(){ final java.util.LinkedList.Node<E> f = first; return (f == null) ? null : f.item; }
//出队(从后端),获得最后一个元素,不存在会返回null,不会删除元素(节点) public E peekLast(){ final java.util.LinkedList.Node<E> l = last; return (l == null) ? null : l.item; }
//出队(从前端),获得第一个元素,不存在会返回null,会删除元素(节点) public E pollFirst(){ final java.util.LinkedList.Node<E> f = first; return (f == null) ? null : unlinkFirst(f); }
//出队(从后端),获得最后一个元素,不存在会返回null,会删除元素(节点) public E pollLast(){ final java.util.LinkedList.Node<E> l = last; return (l == null) ? null : unlinkLast(l); }
public Object clone(){ java.util.LinkedList<E> clone = superClone(); clone.first = clone.last = null; clone.size = 0; clone.modCount = 0; for (java.util.LinkedList.Node<E> x = first; x != null; x = x.next) clone.add(x.item); return clone; }
public Object[] toArray() { Object[] result = new Object[size]; int i = 0; for (java.util.LinkedList.Node<E> x = first; x != null; x = x.next) result[i++] = x.item; return result; } @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { if (a.length < size) a = (T[])java.lang.reflect.Array.newInstance( a.getClass().getComponentType(), size); int i = 0; Object[] result = a; for (java.util.LinkedList.Node<E> x = first; x != null; x = x.next) result[i++] = x.item;