码迷,mamicode.com
首页 > 编程语言 > 详细

Java类集框架之LinkedList源码剖析

时间:2015-05-24 21:40:43      阅读:138      评论:0      收藏:0      [点我收藏+]

标签:

LinkedList

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

 

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

 

public class LinkedList extends AbstractSequentialList implements List, Deque, Cloneable, java.io.Serializable
{
	//元素个数
    transient int size = 0;
 
    //指向第一个节点
    transient Node first;

    //指向最后一个节点
    transient Node last;

    //构造方法1--构造一个空列表
    public LinkedList() {}

    //构造方法2--构造一个包含指定collection中元素的列表,按collection的迭代器返回的顺序排列
    public LinkedList(Collection c) {
        this();
        addAll(c);
    }
    
    //将e插入到链表第一个位置前面,注意可能修改last和first
    private void linkFirst(E e) {
        final Node f = first;
        final Node 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 l = last;
        final Node 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 succ) {
        // assert succ != null;
        final Node pred = succ.prev;
        final Node newNode = new Node<>(pred, e, succ);
        succ.prev = newNode;
        if (pred == null)
            first = newNode;
        else
            pred.next = newNode;
        size++;
        modCount++;
    }

    //去除链表第一个元素
    private E unlinkFirst(Node f) {
        // assert f == first && f != null;
        final E element = f.item;
        final Node 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 l) {
        // assert l == last && l != null;
        final E element = l.item;
        final Node 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 x) {
        // assert x != null;
        final E element = x.item;
        final Node next = x.next;
        final Node 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 f = first;
        if (f == null)
            throw new NoSuchElementException();
        return f.item;
    }

    //获取第一个元素,若为空,抛出异常
    public E getLast() {
        final Node l = last;
        if (l == null)
            throw new NoSuchElementException();
        return l.item;
    }

    //去除第一个元素
    public E removeFirst() {
        final Node f = first;
        if (f == null)
            throw new NoSuchElementException();
        return unlinkFirst(f);
    }

    //去除最后一个元素
    public E removeLast() {
        final Node 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 x = first; x != null; x = x.next) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node 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 c) {
        return addAll(size, c);
    }
    //从LinkedList的index开始,将集合c中的元素添加到LinkedList中
    public boolean addAll(int index, Collection c) {
        checkPositionIndex(index);

        Object[] a = c.toArray();
        int numNew = a.length;
        if (numNew == 0)//集合c为空,返回false
            return false;

        Node 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 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 x = first; x != null; ) {
            Node 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 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 node(int index) {
        // assert isElementIndex(index);
    	//若要查找位置小于双向链表的一半,则从前往后查找,否则从后往前查找,提高查找效率
        if (index < (size >> 1)) {
            Node x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node 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 x = first; x != null; x = x.next) {
                if (x.item == null)
                    return index;
                index++;
            }
        } else {
            for (Node 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 x = last; x != null; x = x.prev) {
                index--;
                if (x.item == null)
                    return index;
            }
        } else {
            for (Node 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 f = first;
        return (f == null) ? null : f.item;
    }
    //返回第一个节点元素,若为空抛出异常,相当于出队
    public E element() {
        return getFirst();
    }

    //出队,获取并移除表头
    public E poll() {
        final Node 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 f = first;
        return (f == null) ? null : f.item;
     }


    public E peekLast() {
        final Node l = last;
        return (l == null) ? null : l.item;
    }


    public E pollFirst() {
        final Node f = first;
        return (f == null) ? null : unlinkFirst(f);
    }


    public E pollLast() {
        final Node 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 x = last; x != null; x = x.prev) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node x = last; x != null; x = x.prev) {
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }

    //返回index到末尾的全部节点对应的ListIterator对象
    public ListIterator listIterator(int index) {
        checkPositionIndex(index);
        return new ListItr(index);
    }
    
    //List迭代器
    private class ListItr implements ListIterator {
        private Node lastReturned;//上一次返回的节点
        private Node 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 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 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() 等方法,为了区分不同的操作,很多方法名不一样,但是功能是一样的。

Java类集框架之LinkedList源码剖析

标签:

原文地址:http://www.cnblogs.com/tujoin/p/4526389.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!