LinkedList源码学习笔记

LinkedList是基于链表的,继承了AbstractSequentialList<E>,实现了List<E>、Deque<E>、Cloneable、Serializable接口,其中Deque<E>为双端队列,LinkedList是双向循环链表。

(一)LinkedList的俩个属性:

(1)privatetransient Entry<E> header = newEntry<E>(null, null,null);

(2)privatetransientintsize = 0;

size即LinkedList中存储的元素个数,header就是链表的头结点,同ArrayList一样,元素也被transient修饰,不可序列化。Entry<E>为LinkedList的内部类:(相当于一个实体类,由于LinkedList是基于链表的,每个元素只与他的前一个元素和后一个元素有关,所以每个元素除了包含本身,还包括他的前一个元素和后一个元素)

privatestaticclass Entry<E> {

    E element;                     //存储的元素

    Entry<E> next;                 //下一个元素

    Entry<E> previous;             //前一个元素

    Entry(E element,Entry<E> next, Entry<E> previous){

        this.element = element;

        this.next = next;

        this.previous = previous;

    }

 }

(二)LinkedList的俩个构造方法

(1)public LinkedList() {

header.next = header.previous = header;

}

(2)public LinkedList(Collection<? extends E> c){

           this();

           addAll(c);

}

(1)初始化一个空链表,从(1)就可以看出LinkedList是一个双向循环链表,(如果不是循环链表,空链表的情况应该是header节点的前一节点和后一节点均为null),此时的结构为:

 

(2)先初始化一个空链表,然后将集合c添加到此链表,addAll(c)方法如下:(在header前添加c)

publicboolean addAll(Collection<? extendsE> c) {

return addAll(size, c);

}

调用重载方法addAll(int index, Collection<? extends E> c):

publicboolean addAll(intindex,Collection<? extends E>c){

//如果index<0index>size则抛出异常

if (index < 0 || index > size)

           throw new IndexOutOfBoundsException

("Index:"+index+ ", Size: "+size);

Object[] a = c.toArray();      //把集合c转换成数组

      intnumNew = a.length;         //数组的长度

      if(numNew==0)                 

         returnfalse;

       modCount++;

//successor指要插入的位置的元素(e的后一个元素)index等于size时,successor

//指向头部header,否则指index处的元素

     Entry<E> successor = (index==size ? header : entry(index));

//predecessorsuccessor的前一个元素(e的前一个元素)

      Entry<E> predecessor = successor.previous;

       for (inti=0; i<numNew; i++) {

//加入链表的每一个元素

        Entry<E> e = newEntry<E>((E)a[i], successor, predecessor);

//predecessor的下一个元素设为e

         predecessor.next = e;

//successor的前一个元素predecessor设为e

         predecessor = e;

      }

//predecessor赋值给successor.previous

      successor.previous = predecessor;

      size += numNew;

      returntrue;

}

双向循环列表要知道每一个元素相邻的前后元素,加入的每一个元素e的之前的元素是predecessor,之后的元素是successor,新加入后predecessor.next变为e,successor.previous变为e。

      获得指定位置的元素的entry(intindex)方法为:

private Entry<E> entry(intindex) {

        if(index < 0 || index>= size)

            thrownew IndexOutOfBoundsException("Index: "+index+ ", Size: "+size);

        Entry<E> e= header;

//移位运算:>>为右移,右移一位相当于除以2,右移n位相当于除//2n次方,<<为左//移,左移n位相当于乘以2n次方。使用移位运算代替乘除法效率要高的多。

//在此判断index如果<1/2size则从header往后查找,如果//index>1/2size则从//header往前查找。

        if(index < (size>> 1)) {

            for(inti = 0; i <= index; i++)

                e= e.next;

        } else{

            for(inti = size; i > index;i--)

                e= e.previous;

        }

        returne;

    }

(三)LinkedList的添加方法

//List里的添加方法:

publicboolean add(E e) {

    addBefore(e,header);

        returntrue;

}

 

publicvoidadd(intindex, E element) {

addBefore(element, (index==size ? header :

                                  entry(index)));

}

 

//队列里的添加方法:

publicvoidaddFirst(E e) {

addBefore(e, header.next);

}

 

publicvoidaddLast(E e) {

    addBefore(e,header);

}

 

publicboolean offer(E e) {

        return add(e);

}

 

publicboolean offerFirst(E e) {

        addFirst(e);

        returntrue;

 }

 

publicboolean offerLast(E e) {

        addLast(e);

        returntrue;

 }

 

publicvoidpush(E e) {                  //栈的实现方法

        addFirst(e);

}

可见底层调用的都是addBefore(Ee, Entry<E> entry):

privateEntry<E> addBefore(E e,Entry<E> entry) {

     Entry<E> newEntry= new Entry<E>(e, entry,

                                         entry.previous);

     //相当于更改指针

        newEntry.previous.next= newEntry;

        newEntry.next.previous = newEntry;

        size++;

        modCount++;

        returnnewEntry;

}

 

                                   

(四)LinkedList的删除方法

//List里的删除方法:

publicboolean remove(Object o) {

if(o==null){

for (Entry<E> e= header.next; e != header; e= e.next) {

           if (e.element==null) {

             remove(e);

             returntrue;

          }

      }

   } else{

     for (Entry<E> e= header.next; e != header; e= e.next) {

          if (o.equals(e.element)) {

                remove(e);

                 returntrue;

             }

         }

      }

        returnfalse;

 }

 

public E remove(intindex) {

        return remove(entry(index));

}

 

//队列里的删除方法:

public E removeFirst() {

    returnremove(header.next);

}

 

public E removeLast() {

    returnremove(header.previous);

}

public E poll() {               //当队列为空时返回null

        if(size==0)

            returnnull;

        return removeFirst();

}

 

public E remove() {              //当队列为空时抛出异常

        return removeFirst();

}

 

public E pollFirst() {

        if(size==0)

            returnnull;

        return removeFirst();

}

 

public E pollLast() {

        if(size==0)

            returnnull;

        return removeLast();

}

 

public E pop() {                    //栈的实现方法

        return removeFirst();

}

 

publicboolean removeFirstOccurrence(Object o){

        return remove(o);

}

//由于是双向循环链表,header.previous就是最后一个元素,从后往前找

publicboolean removeLastOccurrence(Object o){

if(o==null){

        for(Entry<E> e = header.previous; e != header;e = e.previous)

{

            if (e.element==null) {

                remove(e);

                returntrue;

             }

         }

     } else{

         for(Entry<E> e = header.previous; e != header;e = e.previous)

 {

             if(o.equals(e.element)) {

                 remove(e);

                 returntrue;

              }

          }

      }

        returnfalse;

}

删除的方法底层调用的都是remove(Entry<E>e)方法:

private E remove(Entry<E> e) {

if(e == header)

        thrownew NoSuchElementException();

E result = e.element;

//相当于更改指针

    e.previous.next = e.next;

    e.next.previous = e.previous;

//e的前后元素以及自身都设为null

    e.next = e.previous = null;

    e.element = null;

    size--;

    modCount++;

    returnresult;

}

(五)LinkedList的查找方法

//list的查找方法:

public E get(intindex) {

        return entry(index).element;

}

 

publicintindexOf(Object o) {

intindex = 0;

    if(o==null){

        for (Entry e = header.next; e != header;e = e.next) {

            if (e.element==null)

                returnindex;

                index++;

        }

     } else{

       for (Entry e = header.next; e != header;e = e.next) {

             if(o.equals(e.element))

                returnindex;

                index++;

        }

     }

       return -1;

 }

 

publicintlastIndexOf(Object o) {

intindex = size;

    if(o==null){

        for (Entry e = header.previous; e != header;e = e.previous) {

            index--;

            if(e.element==null)

                returnindex;

        }

     } else{

       for (Entry e = header.previous; e != header;e = e.previous) {

            index--;

            if(o.equals(e.element))

                returnindex;

        }

     }

       return -1;

}

 

//Deque的查找方法:

public E getFirst() {

    if (size==0)

        thrownew NoSuchElementException();

 

    returnheader.next.element;

}

 

public E getLast() {

    if (size==0)

        thrownew NoSuchElementException();

 

    returnheader.previous.element;

}

 

public E peek() {              //如果链表为空,返回null

    if(size==0)

        returnnull;

    return getFirst();

}

 

public E element() {          //如果链表为空,抛出异常

     return getFirst();

}

 

public E peekFirst() {

     if(size==0)

         returnnull;

     return getFirst();

}

 

public E peekLast() {

     if(size==0)

         returnnull;

     return getLast();

}

添加、删除和查找的方法分为List实现和queue实现,因为LinkedList实现了List和Deque接口,当作为List使用时采用List的方法,作为Queue使用时,用队列的方法。

(六)LinkedList的更改方法

//element替换index处的元素

public E set(intindex, E element){

Entry<E> e= entry(index);

    E oldVal = e.element;

    e.element = element;

    returnoldVal;

}

 

(七)LinkedList的遍历方法:

//index处开始遍历,返回一个迭代器

public ListIterator<E> listIterator(intindex) {   

    returnnew ListItr(index);

}

ListItr是一个内部类:

privateclass ListItr implements ListIterator<E> {

    privateEntry<E> lastReturned = header;

    privateEntry<E> next;

    privateintnextIndex;

    privateintexpectedModCount= modCount;

    ListItr(intindex) {

        if (index < 0 || index> size)

           thrownew IndexOutOfBoundsException("Index: "+index+

                         ", Size: "+size);

        if (index < (size>> 1)) {

       next = header.next;

       for(nextIndex=0; nextIndex<index; nextIndex++)

          next = next.next;

        } else {

       next = header;

       for(nextIndex=size; nextIndex>index; nextIndex--)

          next = next.previous;

        }

    }

**省略接口里的其他方法**

}

遍历的例子:

publicclass TestLinkedList {

    publicstaticvoidmain(String[] args) throws ClassNotFoundException {

       LinkedList<String> list = new LinkedList<String>();

       list.add("haha");

       list.add("heihei");

       list.add("xixi");

//获得迭代器,从第二个元素(heihei)开始遍历

       Iterator<String> iterator = list.listIterator(1);

       while(iterator.hasNext()){

           String s= iterator.next();

           System.out.println(s);

       }

    }

}

结果:

(八)其他方法:

//判断list中是否包含o

publicboolean contains(Object o) {

        return indexOf(o) != -1;

}

 

//返回list的大小

publicintsize() {

    returnsize;

}

 

//置空list

publicvoidclear() {

Entry<E> e= header.next;

    while (e != header){

        Entry<E>next = e.next;

        e.next = e.previous = null;

        e.element = null;

        e= next;

    }

    header.next = header.previous = header;

    size = 0;

    modCount++;

}

 

//cloneList 此处为浅复制

public Object clone() {

        LinkedList<E> clone = null;

    try {

        clone = (LinkedList<E>) super.clone();

    } catch (CloneNotSupportedException e){

        thrownew InternalError();

    }

        // Put clone into "virgin" state

        clone.header = new Entry<E>(null,null, null);

        clone.header.next = clone.header.previous = clone.header;

        clone.size = 0;

        clone.modCount = 0;

        // Initialize clone with our elements

        for(Entry<E> e = header.next; e != header;e = e.next)

            clone.add(e.element);

        returnclone;

}

 

//list转换为array

public Object[] toArray() {

    Object[] result= new Object[size];

    inti = 0;

    for (Entry<E> e= header.next; e != header; e = e.next)

         result[i++] = e.element;

    returnresult;

}

public <T> T[] toArray(T[] a) {

if(a.length < size)

//如果数组的大小<list的大小,创建一个指定类型,指定大小的新数组

        a= (T[])java.lang.reflect.Array.newInstance(

                                   a.getClass().getComponentType(), size);

    inti = 0;

    Object[] result= a;

    for(Entry<E> e = header.next; e != header;e = e.next)

         result[i++] = e.element;

//如果数组的大小>list的大小,将不用的置空

    if(a.length > size)

         a[size] = null;

    returna;

}

参考资料:http://blog.youkuaiyun.com/jzhf2012/article/details/8540543

             http://www.cnblogs.com/ITtangtang/p/3948610.html#a6

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值