对LinkedList的理解

首先来看一张图

 LinkedList实现了List接口,所以具有List集合类的一些特征

  1. LinkedList的全面说明

(1) LinkedList底层实现了双向链表和双端队列特点

(2) 可以添加任意元素(元素可以重复),包括null

(3) 线程不安全,没有实现同步

     2.  LinkedList的底层操作机制

(1) LinkedList底层维护了一个双向链表

 (2) LinkedList中维护了两个属性first和last分别指向 首节点和尾节点

transient Node<E> first;

transient Node<E> last;

(3) 每个节点(Node对象),里面又维护了prev、next、item三个属性,其中通过prev指向前一个,通过next指向后一个节点。最终实现双向链表

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;   

          }

}

(4) 所以LinkedList的元素的添加和删除,不是通过数组完成的,相对来说效率较高

3. 源码分析

1. LinkedList list = new LinkedList();

无参构造器

public LinkedList() {

}

2. 这时 linkeList 的属性 first = null last = null

<1>执行add方法

public boolean add(E e) {    

          linkLast(e); //将新加入的节点往后连   

          return true;

}

将新的节点,加入到双向链表的最后

void linkLast(E e) {    

        final Node<E> l = last;  //第一次添加时,last == null    

        final Node<E> newNode = new Node<>(l, e, null);  //此时l == null    

        last = newNode;  // last指向该节点    

        if (l == null)  //第一次l为空       

                  first = newNode;  //first 也指向该节点   

          else      

                   l.next = newNode;  

          size++;   

          modCount++;

}

当执行第二次add方法时(进入linkLast方法后):令l = last (此时last指向第一个节点,所以l此时也指向第一个节点);紧接着把l赋到了新节点(第二个)的prev位置,所以此时新节点指向第一个节点;再令last指向新节点 (保证last指向的永远都是最后一个节点);此时l不为null (l指向第一个节点),执行l.next = newNode; 也就是令第一个节点的next属性指向新节点,此时构成双向链表。

<2>执行remove方法

linkedList.remove();

public E remove() {   

          return removeFirst();

}

这里默认删除的是第一个结点

public E removeFirst() {  

           final Node<E> f = first; //令f指向双向链表的第一个节点   

           if (f == null)        

                 throw new NoSuchElementException();    

           return unlinkFirst(f);

}

执行 unlinkFirst方法, f 指向的双向链表的第一个结点拿掉

private E unlinkFirst(Node<E> f) {    

        // assert f == first && f != null;    

          final E element = f.item; //取出第一个节点的内容  

          final Node<E> next = f.next; //设置next属性指向第二个节点   

          f.item = null; //将第一个节点的内容置为null    

          f.next = null; // help GC    断掉第一个节点的next属性与下一个节点之间的线   

          first = next; //因为next指向的是第二个节点,此时first指向的也是第二个节点   

          if (next == null)       

                  last = null;    

          else        

                  next.prev = null;

//如果第二个节点不为null,则断掉第二个节点的prev属性与第一个节点之间的线(此时第一个节点不指向任何,也没有任何对象指向第一个节点,GC认为其是垃圾将其删除)   

        size--;    

        modCount++;    

        return element;

}

4. ArrayList和LinkedList的比较

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值