容器-ListedList删除指定位置元素的源码分析(十一)

容器-ListedList删除指定位置元素的源码分析(十一)

  1. 根据索引删除元素

    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);
            ]
        }
    
  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方法,也就是删除指定元素的关键方法,就是把要删除的那个节点的两边的节点,想办法断开,在引用到两边的节点。原理图:
      在这里插入图片描述

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页