LinkedList源码剖析

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

由上源码可知:
LinkedList 是一个继承于AbstractSequentialList的双向链表。
LinkedList 实现 List 接口,能对它进行队列操作。
LinkedList 实现 Deque 接口,(Deque就是双向队列的接口),即能将LinkedList当作双端队列使用。
LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。
LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。LinkedList 是非同步的。

1.构造函数

   transient Node<E> first;//指向第一个节点的指针。
    transient Node<E> last;//指向最后一个节点的指针。
    public LinkedList() {
    }

    /*
    * 按照集合的迭代器返回元素的顺序,构造包含指定集合的元素的列表
     */
    public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);
    }

LinkedLIst的构造函数主要分为两种,一种是有参构造,一种是无参构造

2.元素的插入

/**
  /**
    在此列表的开头插入指定的元素。
     */
    public void addFirst(E e) {
        linkFirst(e);
    }

    /**
     将指定的元素追加到此列表的末尾
     */
    public void addLast(E e) {
        linkLast(e);
    }
    /*
   在此列表中的指定位置插入指定的元素。将当前位于该位置的元素(如果有的话)和任何后续元素    移到右边(在其索引中添加一个元素)。
     */
    public void add(int index, E element) {
        checkPositionIndex(index);

        if (index == size)
            linkLast(element);
        else
            linkBefore(element, node(index));
    }
     */

由上源码可以看到在LinkedList中插入元素的时候,主要有三种情况:1.头插;2.尾插;3.在指定位置插入元素(当指定位置存在元素的时候,将当前位于该位置的元素(如果有的话)和任何后续元素 移到右边)

3.元素的删除

/**
    移除此列表中指定位置的元素。向左移动任何后续元素(从其索引中减去一个元素)。返回从列表中删除的元素。
     */
    public E remove(int index) {
        checkElementIndex(index);
        return unlink(node(index));
    }
     /**
    删除链表中指定元素,如果指定元素存在,则从此列表中移除指定元素的第一个匹配项。如果此列表不包含元素,则它将保持不变。
     */
    public boolean remove(Object o) {
        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;
    }

LinkedList中删除元素的时候,只需要改变指针,对比ArrayList,当需要进行频繁的插入、删除操作的时候,选择LinkedList,因为在链表中进行插入删除操作,不需要像ArrayLIst一样对数据进行整体的移动。

4.遍历


    public ListIterator<E> listIterator(int index) {
        checkPositionIndex(index);
        return new ListItr(index);
    }

    private class ListItr implements ListIterator<E> {
        private Node<E> lastReturned;
        private Node<E> next;
        private int nextIndex;
        private int expectedModCount = modCount;

        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;
            next = next.next;
            nextIndex++;
            return lastReturned.item;
        }

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

        public E previous() {
            checkForComodification();
            if (!hasPrevious())
                throw new NoSuchElementException();

            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();
            if (lastReturned == null)
                throw new IllegalStateException();

            Node<E> lastNext = lastReturned.next;
            unlink(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();
        }
    }
    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();
        }
    }

LinkedList有两种遍历方式,分别是Iterator、和逆向遍历ListIterator;Iterator中具备的功能只有hashNext(),next(),remove(); ListIterator中具备着对被遍历的元素进行增删改查的方法,可以对元素进行逆向遍历。

你可能感兴趣的:(java)