Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3648402
  • 博文数量: 365
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2522
  • 用 户 组: 普通用户
  • 注册时间: 2019-10-28 13:40
文章分类

全部博文(365)

文章存档

2023年(8)

2022年(130)

2021年(155)

2020年(50)

2019年(22)

我的朋友

分类: Java

2021-06-15 17:21:07

/**

     * Constructs an empty list.

     */

    public LinkedList() {

    }

    /**

     * Constructs a list containing the elements of the specified

     * collection, in the order they are returned by the collection's

     * iterator.

     *

     * @param  c the collection whose elements are to be placed into this list

     * @throws NullPointerException if the specified collection is null

     */

    public LinkedList(Collection c) {

        //调用无参构造,其实就是个空方法

        this();

        //添加全部元素至LinkedList

        addAll(c);

    }

    //addAll方法,此时对于新建的LinkedList实例,size=0

    public boolean addAll(Collection c) {

        return addAll(size, c);

    }

    /**

     * Inserts all of the elements in the specified collection into this

     * list, starting at the specified position.  Shifts the element

     * currently at that position (if any) and any subsequent elements to

     * the right (increases their indices).  The new elements will appear

     * in the list in the order that they are returned by the

     * specified collection's iterator.

     *

     * @param index index at which to insert the first element

     *              from the specified collection

     * @param c collection containing elements to be added to this list

     * @return {@code true} if this list changed as a result of the call

     * @throws IndexOutOfBoundsException {@inheritDoc}

     * @throws NullPointerException if the specified collection is null

     */

    public boolean addAll(int index, Collection c) {

        //越界检查

        checkPositionIndex(index);

        //Collection入参转换为数组

        Object[] a = c.toArray();

        //检查入参中是否包含元素,如果返回false,说明有参构造的Collection参数不包含元素

        int numNew = a.length;

        if (numNew == 0)

            return false;

        //链表节点Node

        Node pred, succ;

        //验证index是否==size,如果等于,则在链表last元素后追加新元素

        if (index == size) {

            succ = null;

            pred = last;

        } else {

            //如不等于,则获取下标为index元素,

            succ = node(index);

            pred = succ.prev;

        }

        //循环入参中的元素

        for (Object o : a) {

            @SuppressWarnings("unchecked") E e = (E) o;

            //新建一个节点,不包含next下一节点

            Node newNode = new Node<>(pred, e, null);

            如果新建节点next==null,说明是头节点

            if (pred == null)

                first = newNode;

            else

                //否则,将前节点的next引用指向新建节点

                pred.next = newNode;

            pred = newNode;

        }

        //循环结束,如果传入index为链表长度,最后一次循环得到pred就是尾节点

        if (succ == null) {

            last = pred;

        } else {

            //如果index不等于size,说明是从中间插入的,最后一个元素也有下一节点

            //该下一节点就是之前下标为index的元素

            pred.next = succ;

            succ.prev = pred;

        }

        //链表元素数量增加

        size += numNew;

        //迭代器需要用到的修改次数,若不为0,使用迭代器遍历会报错

        modCount++;

        return true;

    }

    //越界检查

    private void checkPositionIndex(int index) {

        if (!isPositionIndex(index))

            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));

    }

    //越界检查

    private boolean isPositionIndex(int index) {

        return index >= 0 && index <= size;

    }

    //链表中节点,包含自身引用及前后节点引用

    //这样,链表中的节点便是包含前一节点和后一节点引用(除去首尾节点)

    private static class Node {

        E item;

        Node next;

        Node prev;

        Node(Node prev, E element, Node next) {

            this.item = element;

            this.next = next;

            this.prev = prev;

        }

    }

    /**

     * Returns the (non-null) Node at the specified element index.

     * 返回指定位置的非空节点

     * 节点如果为空

     */

    Node node(int index) {

        // assert isElementIndex(index);

        //index大于size的一半,则从链表头部开始向下遍历处理

        if (index < (size >> 1)) {

            Node x = first;

            //从头遍历,找到下标为index的元素(同数组的下标)

            //也就是说秒如果index=4,得到的,是第五个元素

            for (int i = 0; i < index; i++)

                x = x.next;

            return x;

        } else {

            //否则,则从链表尾部开始向上遍历处理

            Node x = last;

            //从尾巴节点的前节点开始找,假如size=8.index = 6.实际得到的,相当于数组中下标为7的元素

            for (int i = size - 1; i > index; i--)

                x = x.prev;

            return x;

        }

    }

阅读(680) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~