JAVA 集合类(java.util)源码阅读笔记------LinkedList

一、继承关系

public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable

(1)继承自AbstractSequentialList抽象类(该类继承自AbstractList抽象类);实现了List、Deque、Cloneable和Serializable接口,对随机get、set、remove等做了基本实现。
(2)AbstractSequentialList抽象类:定义了具体方法get()、set()、add()、remove()、addAll()(提供对list的随机访问功能)和抽象方法abstract ListIterator<E> listIterator(int index)。
(3)Deque:双向队列,可以用作栈。继承自Queue接口,Queue接口又继承自Collection接口。
(4)实现方式是采用一个链表的形式。
(5)LinkedList可以被当作堆栈(实现了Deque接口)、队列或双端队列进行操作。


二、成员变量

transient int size = 0;//包含元素的个数
transient Node<E> first;//指向链表的第一个元素的指针
transient Node<E> last;//指向链表的最后一个元素的指针

三、方法说明

(1)addFirst:链表头部添加一个新元素,调用私有方法linkFirst实现

	public void addFirst(E e) {
        linkFirst(e);
    }
 //linkFirst:在链表首添加一个元素
 private void linkFirst(E e) {
        final Node<E> f = first;
		//new Node<>(指向前一个节点的指针,数据,指向后一个节点的指针)
        final Node<E> newNode = new Node<>(null, e, f);
        first = newNode;
		//链表原先为空,现在添加了一个节点,last指针和first指针都指向该节点
        if (f == null)
            last = newNode;
		//原先的首节点的prev指针指向新节点
        else
            f.prev = newNode;
        size++;
		//修改次数+1
        modCount++;
    }


(2)addLast、add:在链表尾部添加一个新节点,调用私有方法linkLast实现

	public void addLast(E e) {
        linkLast(e);
    }
	类似的还有add方法也是调用linkLast实现
	public boolean add(E e) {
        linkLast(e);
        return true;
    }
	linkLast:在链表的最后添加一个节点
	void linkLast(E e) {
        final Node<E> l = last;
		//新节点的prev指针指向原先的最后一个节点
        final Node<E> newNode = new Node<>(l, e, null);
		//修改last指针指向新的最后一个节点
        last = newNode;
        if (l == null)
            first = newNode;
		//原先的最后一个节点的next指针指向新节点
        else
            l.next = newNode;
        size++;
        modCount++;
    }


(3)linkBefore:在succ节点之前添加节点,如果succ为null会抛出异常

	void linkBefore(E e, Node<E> succ) {
        // assert succ != null;
        final Node<E> pred = succ.prev;//succ的前一个节点
        final Node<E> newNode = new Node<>(pred, e, succ);
        succ.prev = newNode;
		//succ是首节点
        if (pred == null)
            first = newNode;
		//succ的前一个节点的next指向新节点
        else
            pred.next = newNode;
        size++;
        modCount++;
    }


(4)removeFirst:删除链表的头节点

	public E removeFirst() {
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return unlinkFirst(f);
    }
//unlinkFirst:删除链表中第一个节点,并取消链接(prev和next),私有方法,供removeLast()调用
//使用前提:f!=null,否则会抛出异常;并且f是链表的第一个节点,否则结果会删除链表首节点到f位置的所有节点(first=f.next)
	private E unlinkFirst(Node<E> f) {
        // assert f == first && f != null;
        final E element = f.item;
        final Node<E> next = f.next;
        f.item = null;
        f.next = null; // help GC
        first = next;
		//链表中已经没有节点了
        if (next == null)
            last = null;
        else
            next.prev = null;
        size--;
        modCount++;
        return element;
    }


(5)removeLast:删除链表的最后一个节点

	public E removeLast() {
        final Node<E> l = last;
        if (l == null)
            throw new NoSuchElementException();
        return unlinkLast(l);
    }
//unlinkLast:删除链表的最后一个节点,并删除链接,私有方法,供removeFirst方法调用
//使用前提:f!=null,否则会抛出异常;并且l是链表的最后一个节点,否则会删除f到链表尾部的所有节点(last=l.prev)
private E unlinkLast(Node<E> l) {
        // assert l == last && l != null;
        final E element = l.item;
        final Node<E> prev = l.prev;
        l.item = null;
        l.prev = null; // help GC
        last = prev;
		//该链表中已经没有节点了
        if (prev == null)
            first = null;
        else
            prev.next = null;
        size--;
        modCount++;
        return element;
    }


(6)unlink:删除一个节点,并删除该节点的prev和next链接,修改前后节点的链接

//x!=null,否则会抛出异常
	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是首节点
        if (prev == null) {
            first = next;
        } else {
		//取消prev和x两个节点之间的链接
            prev.next = next;
            x.prev = null;
        }
		//x是尾节点
        if (next == null) {
            last = prev;
        } else {
		//取消next和x两个节点之间的链接
            next.prev = prev;
            x.next = null;
        }

        x.item = null;
		//链表size减一
        size--;
		//增加修改次数
        modCount++;
		//返回删除节点的数据部分
        return element;
    }


(7)删除指定的节点,需要调用unlink

	public boolean remove(Object o) {
	//当o==null时,通过==判断x.item与o是否相当,否则,通过o.equals(x.item)来判断是否相等
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }


(8)在指定的index处添加多个节点

	public boolean addAll(int index, Collection<? extends E> c) {
        checkPositionIndex(index);

        Object[] a = c.toArray();
        int numNew = a.length;
        if (numNew == 0)
            return false;

        Node<E> pred, succ;
		//在队列尾部添加
        if (index == size) {
            succ = null;
            pred = last;
        } else {
		//succ指向链表中第index个节点,pred指向succ节点的前一个节点,c中的元素需要添加在pred和succ之间
            succ = node(index);
            pred = succ.prev;
        }
		//逐个添加,将pred与新节点之间的链接建立起来
        for (Object o : a) {
            @SuppressWarnings("unchecked") E e = (E) o;
			//新节点的prev指向pred
            Node<E> newNode = new Node<>(pred, e, null);
			//添加的是首节点
            if (pred == null)
                first = newNode;
            else
			//pred的next指向新节点
                pred.next = newNode;
			//pred向后移动
            pred = newNode;
        }
		//将添加的最后一个节点与succ之间的链接建立起来
        if (succ == null) {
            last = pred;
        } else {
            pred.next = succ;
            succ.prev = pred;
        }
		//修改链表的大小
        size += numNew;
		//修改次数+1
        modCount++;
        return true;
    }


(9)重写了Object的clone方法,该类的父类或者父接口实现了cloneable接口,因此该类间接的实现了cloneable接口

    public Object clone() {
        LinkedList<E> clone = superClone();

        // Put clone into "virgin" state
        clone.first = clone.last = null;
        clone.size = 0;
        clone.modCount = 0;

        // 深复制,但是如果item是一个引用类型数据,则原链表中节点的item与新clone的链表节点中item指向的仍然是同一个对象。
        for (Node<E> x = first; x != null; x = x.next)
            clone.add(x.item);

        return clone;
    }


四、内部类

(1) Node:链表的节点类,是一个有两个指针的节点

	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;
        }
    }


(2) ListItr:链表的双向迭代器

	private class ListItr implements ListIterator<E> {
        private Node<E> lastReturned;//上一次操作的节点
        private Node<E> next;//指向节点的指针
        private int nextIndex;//next是链表的第几个节点
		//为了检查当一个线程在对该链表操作时,是否有另一个线程在对该链表进行增删改操作,如果有,就抛出ConcurrentModificationException异常
        private int expectedModCount = modCount;
		//index指向的是该节点器的起始节点在原链表中的位置
        ListItr(int index) {
            // assert isPositionIndex(index);
            next = (index == size) ? null : node(index);
            nextIndex = index;
        }

        public boolean hasNext() {
            return nextIndex < size;
        }

        public E next() {
            checkForComodification();
            if (!hasNext())
                throw new NoSuchElementException();
			//lastReturned指向next的前一个节点
            lastReturned = next;
            next = next.next;
            nextIndex++;
            return lastReturned.item;
        }

        public boolean hasPrevious() {
            return nextIndex > 0;
        }

        public E previous() {
            checkForComodification();
            if (!hasPrevious())
                throw new NoSuchElementException();
			//lastReturned指向next同一个节点
            lastReturned = next = (next == null) ? last : next.prev;
            nextIndex--;
            return lastReturned.item;
        }

        public int nextIndex() {
            return nextIndex;
        }

        public int previousIndex() {
            return nextIndex - 1;
        }

		
        public void remove() {
            checkForComodification();
			//检查lastReturned是否为空
            if (lastReturned == null)
                throw new IllegalStateException();

            Node<E> lastNext = lastReturned.next;
            unlink(lastReturned);
			//当上一次调用的是next时,next!=lastReturned;当上一次调用的是previous时,next==lastReturned
            if (next == lastReturned)
                next = lastNext;
            else
                nextIndex--;
            lastReturned = null;
            expectedModCount++;
        }

        public void set(E e) {
            if (lastReturned == null)
                throw new IllegalStateException();
            checkForComodification();
            lastReturned.item = e;
        }

        public void add(E e) {
            checkForComodification();
            lastReturned = null;
            if (next == null)
                linkLast(e);
            else
                linkBefore(e, next);
            nextIndex++;
            expectedModCount++;
        }

        public void forEachRemaining(Consumer<? super E> action) {
            Objects.requireNonNull(action);
            while (modCount == expectedModCount && nextIndex < size) {
                action.accept(next.item);
                lastReturned = next;
                next = next.next;
                nextIndex++;
            }
            checkForComodification();
        }

        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }


(3)链表逆向迭代器:通过itr.previous()实现

	/**
     * Adapter to provide descending iterators via ListItr.previous
     */
    private class DescendingIterator implements Iterator<E> {
        private final ListItr itr = new ListItr(size());
        public boolean hasNext() {
            return itr.hasPrevious();
        }
        public E next() {
            return itr.previous();
        }
        public void remove() {
            itr.remove();
        }
    }


(4)LLSpliterator: 并行迭代器

java1.8新添加的,在Collection接口中用default关键字定义,提供了默认实现。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值