zoukankan      html  css  js  c++  java
  • java集合: LinkedList源码浅析

    LinkedList 数据结构是双向链表,插入删除比较方便。
    LinkedList 是线程不安全的,允许元素为null  。

    构造函数:

    构造函数是空的。

      /**
         * Constructs an empty list.
         */
        public LinkedList() {
        }

    基本属性:

      
        //transient表示不会被序列化
       //集合元素数量
        transient int size = 0;
        //链表头节点
        transient Node<E> first;
        //链表尾节点
        transient Node<E> last;

    链表节点: Node<E>

    链表节点通过内部类Node<E>表示,这是一个双向链表。
    既可以从头开始遍历,也可以从尾开始遍历。
    next是上一个节点,prev是下一个节点。

     private static class Node<E> {
             //链表存储的元素
            E item;
            //next表示下一个节点
            Node<E> next;
            //prev表示上一个节点
            Node<E> prev;
    
            Node(Node<E> prev, E element, Node<E> next) {
                this.item = element;
                this.next = next;
                this.prev = prev;
            }
        }

    添加元素: add()

     /**
         * Appends the specified element to the end of this list.
         *
         * <p>This method is equivalent to {@link #addLast}.
         *
         * @param e element to be appended to this list
         * @return {@code true} (as specified by {@link Collection#add})
         */
        public boolean add(E e) {
            linkLast(e);
            return true;
        }

    调用 linkLast()方法。在链表末尾添加新节点。   

      /**
         * Links e as last element.
         */
        void linkLast(E e) {
            final Node<E> l = last;
            final Node<E> newNode = new Node<>(l, e, null);
            last = newNode;
            if (l == null)
                first = newNode;
            else
                l.next = newNode;
            size++;
            modCount++;
        }

    查询链表: get(index)

    使用get(int index)。如下:

     /**
         * Returns the element at the specified position in this list.
         *
         * @param index index of the element to return
         * @return the element at the specified position in this list
         * @throws IndexOutOfBoundsException {@inheritDoc}
         */
        public E get(int index) {
           //检查下标,如果越界就抛异常
            checkElementIndex(index);  
           //遍历双向链表返回结果         
            return node(index).item;
        }
        
    
        private void checkElementIndex(int index) {
            if (!isElementIndex(index))
                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
        }
        
            /**
         * Tells if the argument is the index of an existing element.
         */
        private boolean isElementIndex(int index) {
            return index >= 0 && index < size;
        }

    遍历链表: node(index)

    在用get(index)查询元素时调用了node(index)方法来遍历。
    如果下标小于链表长度的一半,就从头遍历。反之就从尾遍历。这样查找的效率比较高。

      /**
         * Returns the (non-null) Node at the specified element index.
         */
        Node<E> node(int index) {
            // assert isElementIndex(index);
            //  size右移1位,表示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;
            }
        }    
        

    参考博客 :

    https://blog.csdn.net/zxt0601/article/details/77341098

  • 相关阅读:
    poj3635(最短路)
    poj 3041( 最大匹配)
    poj 3522(生成树)
    poj 1904(强连通分量)
    poj 2446(二分匹配)
    poj 2400(最小权匹配)
    poj 2175(费用流消圈)
    poj 1256(搜索)
    poj 2195(最小费用流)
    poj 3613(最短路)
  • 原文地址:https://www.cnblogs.com/expiator/p/10077996.html
Copyright © 2011-2022 走看看