Java LinkedList源码分析(JDK8)

LinkedList简介

LinkedList是Java语言常用的集合,LinkedList的底层是有一个双向双端链表实现的,因此LinkedList继承了链表的特性:插入删除效率很高(时间复杂度O(1)),查询效率较低(时间复杂度O(N)),不需要给出初始容量,一定程度上节约了系统资源。

下面是LinkedList 的属性定义,以及内部类节点Node的定义。
	public class LinkedList<E>
	    extends AbstractSequentialList<E>
	    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
	{
	    transient int size = 0;   //定义了三个变量: size 链表中的元素个数,first 起始节点元素,last 结束节点元素
	    
	    transient Node<E> first; //链表中的第一个元素
	
	    transient Node<E> last; //链表中的最后一个元素
	    // 内部类,定义一个节点的格式,存在前节点,后节点,以及元素对象
	    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;
	        }
	    }
LinkedList的构造方法
		 //无参构造,初始化空链表
        public LinkedList() {
        }
    
         // 有参构造,根据已有集合对象创建链表
        public LinkedList(Collection<? extends E> c) {
            //创建空链表
            this();
            //执行添加元素操作
            addAll(c);
        }
类中用作判断方法
		//  判断索引是否有元素
	    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));
	    }
addAll() 解释
		//向链表追加一个集合的所有对象
	    public boolean addAll(Collection<? extends E> c) {
	        return addAll(size, c);
	    }
	
	  //在指定位置,追加集合的所有元素
	    public boolean addAll(int index, Collection<? extends E> c) {
	       checkPositionIndex(index); //判断指定位置是否合法
	        Object[] a = c.toArray(); //将集合转为数组
	        int numNew = a.length; //集合数据长度
	        if (numNew == 0)
	            return false; //集合长度为null,返回false
	        Node<E> pred, succ; //定义添加位置的临时左节点以及右节点
	        if (index == size) {
	            succ = null; //从末尾开始添加,临时右节点为null
	            pred = last; //临时左节点为尾结点
	        } else {
	            succ = node(index); //根据索引返回节点对象
	            pred = succ.prev;  //记录临时左节点
	        }
	
	        for (Object o : a) {
	            @SuppressWarnings("unchecked") E e = (E) o;
	            //创建节点,三个参数:pred 临时左节点,e 元素, null 下个节点
	            Node<E> newNode = new Node<>(pred, e, null);
	            if (pred == null)
	                first = newNode;  //首部添加,首节点为新节点
	            else
	                pred.next = newNode; //临时左节点的右节点为新节点
	            pred = newNode; //新节点为临时左节点
	        }
	        if (succ == null) {
	            last = pred; //临时右节点为null,说明是整天在链表尾部开始添加,尾部节点为临时左节点
	        } else {
	            pred.next = succ;  //临时左节点的右节点指向临时右节点
	            succ.prev = pred; //临时右节点的左节点指向临时左节点
	        }
	        size += numNew;  //链表元素个数添加
	        modCount++; //变化次数加1
	        return true;  //返回添加成功与否状态
	}
类中使用的在首部、尾部、指定位置添加元素以及删除元素方法
	   	// 私有方法:从链表头部添加元素
	    private void linkFirst(E e) {
	        final Node<E> f = first;
	        // 三个参数: null 上一个节点,e 元素.f 下一个节点,f为下一个节点因为是从头部添加.
	        final Node<E> newNode = new Node<>(null, e, f);
	        first = newNode;   //头部添加,新节点即为头部节点
	        
	        if (f == null)
	            last = newNode;   //添加第一个节点,尾节点为本身
	        else
	            f.prev = newNode;   //不是添加第一个节点,将原来链表头部节点左节点指向新头部节点(双向引用)
	     
	        size++;  //链表元素个数加1
	        modCount++;   //修改次数加1
	    }
	
	    // 从链表尾部添加元素
	    void linkLast(E e) {
	        final Node<E> l = last;
	        //三个参数, l 原来尾节点作为新节点的左节点,e 元素,null 自身为新尾节点,所以为null
	        final Node<E> newNode = new Node<>(l, e, null);
	        last = newNode;
	        if (l == null)
	            first = newNode;   //链表第一个元素添加,首尾节点均为自身
	        else
	            l.next = newNode;  //原尾节点右节点指向新节点
	     
	        size++;    //链表元素个数加1
	        modCount++;    //变化次数加1
	    }
	
	    // 在某节点前面添加元素
	    void linkBefore(E e, Node<E> succ) {
	        final Node<E> pred = succ.prev; // succ 不能为null,否则抛出空指针异常
	        //三个参数:pred succ的左节点作为新节点的左节点,e 元素,succ succ本身作为新节点的右节点
	        final Node<E> newNode = new Node<>(pred, e, succ);
	        succ.prev = newNode;   //succ 的左节点设置成 新节点 
	        
	        if (pred == null)
	            first = newNode;   //首部添加,新节点为首节点
	        else
	            pred.next = newNode;  //succ原左节点的右节点指向新节点
	                
	        size++;   //元素个数加1
	        modCount++;    //变化次数加1
	    }
	
	    //删除首节点
	    private E unlinkFirst(Node<E> f) {
	        final E element = f.item;     // f节点不为空,并且为首节点
	        final Node<E> next = f.next;  // 记录首节点的右节点
	        f.item = null;
	        f.next = null;   // 首节点元素属性置空,有利于垃圾回收
	        first = next;     // 原首节点的右节点为新的首节点
	        
	        if (next == null)
	            last = null; //链表中没有节点了,末节点为null
	        else
	            next.prev = null;  //next为首节点后 左节点需为null

	        size--; 	        //元素个数减1
	        modCount++;   //变化次数加1
	        return element;//返回被删除元素
	    }
	
	    //  删除尾节点
	    private E unlinkLast(Node<E> l) {
	        //  l 不为空,并且为尾节点
	        final E element = l.item;   // 记录尾结点的元素项
	        final Node<E> prev = l.prev;   // 记录尾结点的左节点
	        l.item = null;
	        l.prev = null;   // 尾结点属性置为null,利于垃圾回收
	        last = prev;   // 原尾结点的左节点为新的尾结点
	        
	        if (prev == null)
	            first = null;  //链表已经没有元素了,首节点为null
	        else
	            prev.next = null;  //新尾结点的next 需要为 null
	       
	        size--;  //链表中元素个数减1
	        modCount++; //变化次数加1
	        return element;  //返回被伤处元素
	    }
	
	    // 删除某节点
	    E unlink(Node<E> x) {
	        // x节点不能为null
	        final E element = x.item;   // 记录删除节点的元素
	        final Node<E> next = x.next; // 记录删除节点的右节点
	        final Node<E> prev = x.prev; // 记录删除节点的左节点
	
	        if (prev == null) {
	            first = next;  // 左节点为nul,删除节点为首节点,next做为新的首节点
	        } else {
	            prev.next = next;  // 左节点指向右节点
	            x.prev = null;  // 删除节点的左节点置为null,利于垃圾回收
	        }
	
	        if (next == null) {
	            last = prev; //next为null,删除的是尾结点,尾结点为prev
	        } else {
	            next.prev = prev;  //删除节点的右节点指向伤处节点的左节点
	            x.next = null;  //删除节点的next置为null,利于垃圾回收
	        }
	       
	        x.item = null;  //删除节点元素置为null,利于垃圾回收
	        size--;    //链表中元素个数减1
	        modCount++;   //变化次数加1
	        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);
	    }
	
	    //  从首部添加元素
	    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;
	    }
	
	 	// 删除某数据项
	    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;
	    }
	    
	   	//清空所有元素
	    public void clear() {
	        // 遍历所有都指向null
	        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;    //元素个数为0
	        modCount++;  //变化次数加1
	    }
	
	   	//  获取某个索引的元素值
	    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;  //返回旧元素
	    }
	
	  	//  在某索引节点前添加元素
	    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)); //获取索引的节点并删除
	    }
	    
		//  返回某元素第一次在链表中的索引
	    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;
	    }
	
	    // 返回某元素在链表中的最后一个索引
	    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.
	
	    // 查看链表中是一个元素
	    public E peek() {
	        final Node<E> f = first;
	        return (f == null) ? null : f.item;
	    }
	
	    // 返回第一个元素值,first为null,抛出异常
	    public E element() {
	        return getFirst();
	    }
	
	    // 删除头部节点,并返回头部节点的元素
	    public E poll() {
	        final Node<E> f = first;
	        return (f == null) ? null : unlinkFirst(f);
	    }
	
	    //  删除头部节点,并返回元素,first为null时抛出异常
	    public E remove() {
	        return removeFirst();
	    }
	
	    //  尾部添加元素,并返回Boolean值
	    public boolean offer(E e) {
	        return add(e);
	    }
	
	    // Deque operations
	    // 首部添加元素,并返回Boolean值
	    public boolean offerFirst(E e) {
	        addFirst(e);
	        return true;
	    }
	
	    // 尾部添加,并返回Boolean值
	    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);
	    }
	
	    //	 删除某元素再链表中的最后一个
	    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到尾部的迭代器
	    public ListIterator<E> listIterator(int index) {
	        //检验索引是否合法
	        checkPositionIndex(index);
	        //返回迭代器
	        return new ListItr(index);
	    }
	    //	 输出流
	    private void writeObject(java.io.ObjectOutputStream s)
	        throws java.io.IOException {
	        // Write out any hidden serialization magic
	        s.defaultWriteObject();
	
	        // Write out size
	        s.writeInt(size);
	
	        // Write out all elements in the proper order.
	        for (Node<E> x = first; x != null; x = x.next)
	            s.writeObject(x.item);
	    }
	
	    //	 输入流
	    @SuppressWarnings("unchecked")
	    private void readObject(java.io.ObjectInputStream s)
	        throws java.io.IOException, ClassNotFoundException {
	        // Read in any hidden serialization magic
	        s.defaultReadObject();
	
	        // Read in size
	        int size = s.readInt();
	
	        // Read in all elements in the proper order.
	        for (int i = 0; i < size; i++)
	            linkLast((E)s.readObject());
	    }
	    
		@SuppressWarnings("unchecked")
	    private LinkedList<E> superClone() {
	        try {
	            return (LinkedList<E>) super.clone();
	        } catch (CloneNotSupportedException e) {
	            throw new InternalError(e);
	        }
	    }

	    // 	返回一个浅克隆对象
	    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;
	    }
	
	    //	转为数组
	    public Object[] toArray() {
	        Object[] result = new Object[size];
	        int i = 0;
	        for (Node<E> x = first; x != null; x = x.next)
	            result[i++] = x.item;
	        return result;
	    }
	
	     //	 以正确的顺序返回一个包含此列表中所有元素的数组(从第一个到最后一个元素)
	     //	 返回的数组的运行时类型是指定数组的运行时类型
	    @SuppressWarnings("unchecked")
	    public <T> T[] toArray(T[] a) {
	        if (a.length < size)
	            a = (T[])java.lang.reflect.Array.newInstance(
	                                a.getClass().getComponentType(), size);
	        int i = 0;
	        Object[] result = a;
	        for (Node<E> x = first; x != null; x = x.next)
	            result[i++] = x.item;
	
	        if (a.length > size)
	            a[size] = null;
	
	        return a;
	    }

迭代器,实现了ListIterator接口,可以进行双向迭代

    /**
     * 迭代器内部类
     */
    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);
            //返回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++; //当前索引加1
            //返回上个节点的值
            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等于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();
        }
    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
LinkedListJava中提供的一个双向链表实现类,其内部维护了一个first和last节点,分别表示链表的头和尾。以下是LinkedList源码分析: 1. 声明LinkedList类 ```java 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; } ``` 2. 声明Node类 ```java 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; } } ``` 3. 实现LinkedList的方法 - add(E e)方法:将元素添加到链表末尾 ```java public boolean add(E e) { linkLast(e); return true; } 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++; } ``` - add(int index, E element)方法:将元素插入到指定位置 ```java public void add(int index, E element) { checkPositionIndex(index); if (index == size) linkLast(element); else linkBefore(element, node(index)); } void linkBefore(E e, Node<E> succ) { 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++; } ``` - remove(int index)方法:删除指定位置的元素 ```java public E remove(int index) { checkElementIndex(index); return unlink(node(index)); } E unlink(Node<E> x) { 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--; return element; } ``` - get(int index)方法:获取指定位置的元素 ```java public E get(int index) { checkElementIndex(index); return node(index).item; } Node<E> node(int 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; } } ``` 以上就是LinkedList源码分析,通过对其源码分析,我们可以更深入地理解链表的实现。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Starry-Leo

帮到了您,有闲钱,再打赏哦~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值