容器-ListedList删除指定位置元素的源码分析(十一)
-
根据索引删除元素
import java.util.LinkedList; import java.util.List; public class LinkedListTest { public static void main(String[] args) { List<String> list= new LinkedList<>(); //添加元素 list.add("a"); list.add("b"); list.add("c"); list.add("a"); list.add(2,"aaaa"); //根据索引删除元素 list.remove(2); ] }
-
看remove的源代码,先Ctrl进去
E remove(int index);
-
在用Ctrl+Alt选择remove方法的LinkedList接口实现类
/** * Removes the element at the specified position in this list. Shifts any * subsequent elements to the left (subtracts one from their indices). * Returns the element that was removed from the list. * * @param index the index of the element to be removed * @return the element previously at the specified position * @throws IndexOutOfBoundsException {@inheritDoc} */ public E remove(int index) { checkElementIndex(index);//校验索引是否正常 return unlink(node(index)); }
-
我们看 checkElementIndex(index);方法
private void checkElementIndex(int index) { if (!isElementIndex(index)) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); //如果isPositionIndex返回的是true,再取非,则不执行if条件语句,证明索引没问题 //如果isPositionIndex返回的是false,再取非,则执行if条件语句,抛出异常 }
-
在进去看isElementIndex(index)
/** * Tells if the argument is the index of an existing element. */ private boolean isElementIndex(int index) { return index >= 0 && index < size;//注意这里的是索引要小于元素的个数,不能取等于,因为索引的个数是要比元素的个数少一个数的 }
-
当校验索引没有问题,就要看 unlink方法了,里面还有个node的方法。
public E remove(int index) { checkElementIndex(index);//校验索引是否正常 return unlink(node(index)); }
-
先看node方法
/** * Returns the (non-null) Node at the specified element index. */ Node<E> node(int index) { // assert isElementIndex(index); 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; } }
-
node的原理图
-
然后我们回去看 unlink方法,假设我们现在删除的是索引为2的节点,也就是删除已33为地址的节点。
/** * Unlinks non-null node x. */ E unlink(Node<E> x) { // assert x != null; final E element = x.item;//就是那个被删除的节点返回回去 final Node<E> next = x.next; final Node<E> prev = x.prev; if (prev == null) {//删除的是头节点才会用到 first = next; } else {//假设我们现在删除的是索引为2的节点 prev.next = next; x.prev = null; } if (next == null) {//删除的是最后一个节点,显然现在不是,我们走else last = prev; } else { next.prev = prev; x.next = null; } x.item = null;//把33节点制为空, size--;//元素被删掉一个,被减一个 modCount++; return element;//就是返回那个被删除的节点 }
-
unlink方法,也就是删除指定元素的关键方法,就是把要删除的那个节点的两边的节点,想办法断开,在引用到两边的节点。原理图:
-