LinkList源码讲解

LinkedList的底层数据结构是双向链表

 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;
        }
    }
  1. add()方法

        public boolean add(E e) {
               linkLast(e);
               return true;
           }
       
       void linkLast(E e) {
            	//取出最后一个节点
               final Node<E> l = last;
            	//创建一个新的节点,前节点为l,后节点为null
               final Node<E> newNode = new Node<>(l, e, null);
            	//记录的新的最后一个节点
               last = newNode;
               if (l == null)
                   /** 如果是第一个添加的元素,则first指针指向该结点*/
                   first = newNode;
               else
                   /** 如果不是第一个添加进来的元素,则更新l的后置结点指向新添加的元素结点*/
                   l.next = newNode;
               size++;
               modCount++;
           }
    
  2. get()

       public E get(int index) {
           //检查是否越界
            checkElementIndex(index);
            return node(index).item;
        }
     	/**
         * Returns the (non-null) Node at the specified element index.
         *
         * 根据传入的index值,返回对应的结点node
         */
        // eg1:index=0
        Node<E> node(int index) {
            // assert isElementIndex(index);
    
            /** 如果需要获取的index小于总长度size的一半,则从头部开始向后遍历查找 */
            if (index < (size >> 1)) {
                Node<E> x = first;
                for (int i = 0; i < index; i++) {
                    x = x.next; // 从first结点向后next查找,直到index下标node,返回node
                }
                return x;
            } else { /** 从尾部开始向前遍历查找 */
                Node<E> x = last;
                for (int i = size - 1; i > index; i--) {
                    x = x.prev; // 从last结点向前prev查找,直到index下标node,返回node
                }
                return x;
            }
        }
    
  3. remove(index)

    1. 首先验证是否越界

      	/**
           * 删除元素
           */
          // eg1:elementData中保存了{"a1","a2","a3","a4"},删除第一个元素,即:index=0
          public E remove(int index) {
              /** 校验传入的参数index是否超出了数组的最大下标且下标不为负数,如果超出,则抛出:IndexOutOfBoundsException异常*/
              checkElementIndex(index);
              // eg1:node(index)返回需要删除的结点,即:"a1"
              return unlink(node(index)); /** 断开待删除结点的链接 */
          }
      
    2. 根据传入的index值,返回对应的结点node

         // eg1:index=0
          Node<E> node(int index) {
              // assert isElementIndex(index);
      
              /** 如果需要获取的index小于总长度size的一半,则从头部开始向后遍历查找 */
              if (index < (size >> 1)) {
                  Node<E> x = first;
                  for (int i = 0; i < index; i++) {
                      x = x.next; // 从first结点向后next查找,直到index下标node,返回node
                  }
                  return x;
              } else { /** 从尾部开始向前遍历查找 */
                  Node<E> x = last;
                  for (int i = size - 1; i > index; i--) {
                      x = x.prev; // 从last结点向前prev查找,直到index下标node,返回node
                  }
                  return x;
              }
          }
      
    3. 从链表中删除x结点的链接

          /**
           * Unlinks non-null node x.
           *
           * 从链表中删除x结点的链接。
           */
          // eg1: x  null<--"a1"-->"a2"
          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;
      
              /** x.prev为null,表示x结点为第一个元素*/
              if (prev == null) {
                  first = next; // 更新first头指针为x结点的后置结点
              } else {
                  prev.next = next; // 将x的前置结点与x的后置结点相连接
                  x.prev = null; // 断开x的前置指针
              }
      
              /** x.next为null,表示x结点为最后一个元素*/
              if (next == null) {
                  last = prev;
              } else {
                  next.prev = prev; // 将x的后置结点与x的前置结点相连接
                  x.next = null; // 断开x的后置指针
              }
      
              x.item = null;
              size--;
              modCount++;
              return element;
          }
      
posted @ 2021-02-18 00:03  一个平凡的程序员  阅读(40)  评论(0)    收藏  举报