• JDK7 LinkedList源代码分析


        transient int size = 0;
    
        /**
         * Pointer to first node.
         * Invariant: (first == null && last == null) ||
         *            (first.prev == null && first.item != null)
         */
        transient Node<E> first;
    
        /**
         * Pointer to last node.
         * Invariant: (first == null && last == null) ||
         *            (last.next == null && last.item != null)
         */
        transient Node<E> last;
    
        /**
         * Constructs an empty list.
         */
        public LinkedList() {
        }

    LinkedList的属性和构造方法

    //添加的方法

        public boolean add(E e) {
            linkLast(e);
            return true;
        }
       void linkLast(E e) {
            final Node<E> l = last;//得到最后一个节点
            final Node<E> newNode = new Node<>(l, e, null);//创建一个新节点(他的前一个节点是原集合中的最后一个,元素,他的下一个节点为null)
            last = newNode;//将新添加的节点设置为集合的最后一个节点
            if (l == null)//集合中原本没有元素,则添加第一个节点
                first = newNode;
            else
                l.next = newNode;//集合中有元素,则将原集合中的最后一个节点的下一个节点设置为新添加的节点
            size++;//元素个数+1
            modCount++;
        }

    linkLast的原理是:新添加元素的pre(前一个节点)是原集合中的最后一个元素,新添加元素的next(下一个节点)是null,新添加进来的元素就成了集合的最后一个节点。如果原集合中没有元素(即添加第一个元素),则新添加的元素既是first,也是last.

     在不做其他操作(如删除第一个元素,添加第一个元素)时,first就一直是第一个添加的元素,last就是新添加的元素。

    private void linkFirst(E e) {
            final Node<E> f = first;
            final Node<E> newNode = new Node<>(null, e, f);
            first = newNode;
            if (f == null)
                last = newNode;
            else
                f.prev = newNode;
            size++;
            modCount++;
        }

    linkFirst原理:新添加进来的元素成了新集合的第一个元素,新添加元素的pre为null,新添加元素的next为原集合的fist。如果原集合没有元素,那么第一个添加进来的元素既是first也是last。

    Node类是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;
            }
        }

    取值:先检查查找的索引是否大于等于0且小于等于集合的长度(size)

        public E get(int index) {
            checkElementIndex(index);
            return node(index).item;
        }
     /**
         * 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;
            }
        }

    有两种情况的取值,如果查找的索引在集合长度的二分之一前,从前往后查找,否则从后往前查找。如从第一个元素开始,一直first.next.next.next...直到查找的索引为止。从后往前是last.pre.pre.pre....

     JDK6和JDK7的实现还是挺不一样的,但是原理是一样的。

  • 相关阅读:
    js金额格式化
    npm ERR! code EPERM npm ERR! syscall open npm ERR! path C:\Program Files\nodejs\node_cache\_cacache\
    Java 获取当前时间的年、月、日、小时、分钟、秒数
    获取前(后)x月的日期
    怎么实现鼠标移入第i个li则对应显示第i个div,默认显示第一个LI
    Java计算两个日期相差的天数
    echarts 实现柱状图重叠而不是相互增加
    日期部分相关工具类
    点击li 该li变色
    Silverlight 实现 A* 寻径算法
  • 原文地址:https://www.cnblogs.com/hjy9420/p/5034271.html
Copyright © 2020-2023  润新知