Java类集框架之LinkedList源码剖析

来源:互联网 发布:进入编程模式错误 编辑:程序博客网 时间:2024/06/16 20:31

LinkedList

LinkedList基于双向循环链表实现。也可以被当做堆栈,队列或双端队列进行操作。非线程安全。下面直接贴ArrayList的Java实现(只贴了部分代码),来源JDK1.8.0_25/src.zip。

    /**     * ****双向链表对应的数据结构*********     * 包含:节点值item     *     前驱  pre     *     后继next         * @param <E>     */    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;        }    }

public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable{//元素个数    transient int size = 0;     //指向第一个节点    transient Node<E> first;    //指向最后一个节点    transient Node<E> last;    //构造方法1--构造一个空列表    public LinkedList() {}    //构造方法2--构造一个包含指定collection中元素的列表,按collection的迭代器返回的顺序排列    public LinkedList(Collection<? extends E> c) {        this();        addAll(c);    }        //将e插入到链表第一个位置前面,注意可能修改last和first    private void linkFirst(E e) {        final Node<E> f = first;        final Node<E> newNode = new Node<>(null, e, f);//Node(前驱,元素,后继)        first = newNode;        if (f == null)            last = newNode;//插入前为空则last为其本身        else            f.prev = newNode;//若不为空则头结点前驱指向newnode        size++;        modCount++;    }    //将e插入到链表最后一个元素的后面    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++;    }    //在节点succ前插入元素为e的节点    void linkBefore(E e, Node<E> succ) {        // assert succ != null;        final Node<E> pred = succ.prev;        final Node<E> newNode = new Node<>(pred, e, succ);        succ.prev = newNode;        if (pred == null)            first = newNode;        else            pred.next = newNode;        size++;        modCount++;    }    //去除链表第一个元素    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;    }    //去除链表最后一个元素    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;    }    //删除节点x    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;        if (prev == null) {            first = next;        } else {            prev.next = next;            x.prev = null;        }        if (next == null) {            last = prev;        } else {            next.prev = prev;            x.next = null;        }        x.item = null;        size--;        modCount++;        return element;    }    //获取第一个元素,若为空,抛出异常    public E getFirst() {        final Node<E> f = first;        if (f == null)            throw new NoSuchElementException();        return f.item;    }    //获取第一个元素,若为空,抛出异常    public E getLast() {        final Node<E> l = last;        if (l == null)            throw new NoSuchElementException();        return l.item;    }    //去除第一个元素    public E removeFirst() {        final Node<E> f = first;        if (f == null)            throw new NoSuchElementException();        return unlinkFirst(f);    }    //去除最后一个元素    public E removeLast() {        final Node<E> l = last;        if (l == null)            throw new NoSuchElementException();        return unlinkLast(l);    }    //将元素e添加为链表第一个元素    public void addFirst(E e) {        linkFirst(e);    }    public void addLast(E e) {        linkLast(e);    }    public boolean contains(Object o) {        return indexOf(o) != -1;    }    public int size() {        return size;    }    public boolean add(E e) {        linkLast(e);//添加到最后面        return true;    }        //可以去除null元素,从链表开始查找指定元素o    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的末尾开始,将集合c添加到LinkedList中    public boolean addAll(Collection<? extends E> c) {        return addAll(size, c);    }    //从LinkedList的index开始,将集合c中的元素添加到LinkedList中    public boolean addAll(int index, Collection<? extends E> c) {        checkPositionIndex(index);        Object[] a = c.toArray();        int numNew = a.length;        if (numNew == 0)//集合c为空,返回false            return false;        Node<E> pred, succ;//插入位置的前一个节点和插入位置的节点        if (index == size) {            succ = null;            pred = last;        } else {            succ = node(index);            pred = succ.prev;        }        for (Object o : a) {            @SuppressWarnings("unchecked") E e = (E) o;            Node<E> newNode = new Node<>(pred, e, null);            if (pred == null)                first = newNode;//时刻注意修改first和last            else                pred.next = newNode;            pred = newNode;        }        if (succ == null) {            last = pred;        } else {            pred.next = succ;            succ.prev = pred;        }        size += numNew;//添加后链表大小        modCount++;        return true;    }    //清空双向链表    public void clear() {        for (Node<E> x = first; x != null; ) {            Node<E> next = x.next;            x.item = null;            x.next = null;            x.prev = null;            x = next;        }        first = last = null;        size = 0;        modCount++;    }    // Positional Access Operations    //获取指定位置元素    public E get(int index) {        checkElementIndex(index);        return node(index).item;    }    //设置指定位置元素值,并返回原来的值    public E set(int index, E element) {        checkElementIndex(index);        Node<E> x = node(index);        E oldVal = x.item;        x.item = element;        return oldVal;    }    //-----在index前添加元素值为element的节点----    public void add(int index, E element) {        checkPositionIndex(index);        if (index == size)            linkLast(element);        else            linkBefore(element, node(index));    }    //删除指定位置节点    public E remove(int index) {        checkElementIndex(index);        return unlink(node(index));    }    private boolean isElementIndex(int index) {        return index >= 0 && index < size;    }    private boolean isPositionIndex(int index) {        return index >= 0 && index <= size;    }    private String outOfBoundsMsg(int index) {        return "Index: "+index+", Size: "+size;    }    private void checkElementIndex(int index) {        if (!isElementIndex(index))            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));    }    private void checkPositionIndex(int index) {        if (!isPositionIndex(index))            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));    }    //以前版本是entry,获取指定位置的节点    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;        }    }    // Search Operations    //从前往后查找,返回值为o的节点位置,若不存在返回-1,可查找null位置    //查找的都是第一次出现的    public int indexOf(Object o) {        int index = 0;        if (o == null) {            for (Node<E> x = first; x != null; x = x.next) {                if (x.item == null)                    return index;                index++;            }        } else {            for (Node<E> x = first; x != null; x = x.next) {                if (o.equals(x.item))                    return index;                index++;            }        }        return -1;    }    //从后往前查找,返回值为o的节点位置,若不存在返回-1,可查找null位置    //查找的都是第一次出现的    public int lastIndexOf(Object o) {        int index = size;        if (o == null) {            for (Node<E> x = last; x != null; x = x.prev) {                index--;                if (x.item == null)                    return index;            }        } else {            for (Node<E> x = last; x != null; x = x.prev) {                index--;                if (o.equals(x.item))                    return index;            }        }        return -1;    }    /*******作为队列使用的操作 Queue operations.************/        //返回第一个节点元素,若为空返回null,获取但不移除(不出队)    public E peek() {        final Node<E> f = first;        return (f == null) ? null : f.item;    }    //返回第一个节点元素,若为空抛出异常,相当于出队    public E element() {        return getFirst();    }    //出队,获取并移除表头    public E poll() {        final Node<E> f = first;        return (f == null) ? null : unlinkFirst(f);    }    public E remove() {        return removeFirst();    }    //入队,添加到表尾    public boolean offer(E e) {        return add(e);    }    /**** Deque operations****/            public boolean offerFirst(E e) {        addFirst(e);        return true;    }    public boolean offerLast(E e) {        addLast(e);        return true;    }    public E peekFirst() {        final Node<E> f = first;        return (f == null) ? null : f.item;     }    public E peekLast() {        final Node<E> l = last;        return (l == null) ? null : l.item;    }    public E pollFirst() {        final Node<E> f = first;        return (f == null) ? null : unlinkFirst(f);    }    public E pollLast() {        final Node<E> l = last;        return (l == null) ? null : unlinkLast(l);    }    public void push(E e) {        addFirst(e);    }    public E pop() {        return removeFirst();    }    public boolean removeFirstOccurrence(Object o) {        return remove(o);    }    //去除最后一次出现的指定节点,从后往前查找的第一个节点去除即可  可为null    public boolean removeLastOccurrence(Object o) {        if (o == null) {            for (Node<E> x = last; x != null; x = x.prev) {                if (x.item == null) {                    unlink(x);                    return true;                }            }        } else {            for (Node<E> x = last; x != null; x = x.prev) {                if (o.equals(x.item)) {                    unlink(x);                    return true;                }            }        }        return false;    }    //返回index到末尾的全部节点对应的ListIterator对象    public ListIterator<E> listIterator(int index) {        checkPositionIndex(index);        return new ListItr(index);    }        //List迭代器    private class ListItr implements ListIterator<E> {        private Node<E> lastReturned;//上一次返回的节点        private Node<E> next;//下一个节点        private int nextIndex;//下一个节点索引        //期望的改变计数,用来实现fail-fast机制        private int expectedModCount = modCount;        ListItr(int index) {            // assert isPositionIndex(index);            next = (index == size) ? null : node(index);            nextIndex = index;        }
    public Object clone() {        LinkedList<E> clone = superClone();        // Put clone into "virgin" state        clone.first = clone.last = null;        clone.size = 0;        clone.modCount = 0;        // Initialize clone with our elements        for (Node<E> x = first; x != null; x = x.next)            clone.add(x.item);        return clone;    }

构造函数:

LinkedList构造方法有2种,一个是无参构造方法,建立一个空的链表(头结点null)  另一个是先建立一个空链表,再调用addAll(c)用c中元素初始化。

说明:

LinkedList基于双向循环链表实现的,不存在容量不足和扩容,但是插入和删除的效率高。在插入一个结点时,新建一个node对象,找到插入节点的位置,改变前驱和后继。删除一个结点时,改变删除节点的前驱节点的后继和后继节点的前驱,不需要移动元素。

LinkedList容许元素为null,在查找和删除某元素时,都区分null和非null

LinkedList实现了栈和队列的操作,如push() pop() 等方法,为了区分不同的操作,很多方法名不一样,但是功能是一样的。

1 0