LinkedList<E>源码学习笔记

来源:互联网 发布:故宫淘宝是故宫开的吗 编辑:程序博客网 时间:2024/06/05 21:59

LinkedList这个类里面包含三个内部类:

    private class DescendingIterator implements Iterator {    private class ListItr implements ListIterator<E> {    private static class Entry<E> {
前两个内部类看其实现的接口就知道,是实现集合的遍历的方法,目前暂时不讲集合遍历的方式。

第三个内部类在这里需要仔细说说,先看源码:

    private static class 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;}    }
该类里面定义了三个成员变量:

element——表示的是集合中每个节点所存放的数据,是一个泛型

next、previous——两个成员变量的类型都是该内部类类型,且这两个变量分别存放的是集合中有一个节点和前一个节点的对象引用,这样就将链表首位相连

这个内部类实现的原理其实跟我们学习数据结构中的循环链表是一样的:包含一个头结点,每个节点都包含指向前一个节点的引用、节点所存放的数据、指向后一个节点的引用


LinkedList类中定义了两个私有的成员变量:  

 private transient Entry<E> header = new Entry<E>(null, null, null);//链表的头节点,不包含任何真是的数据,只标识这是循环链表的初始位置 private transient int size = 0;//记录循环链表中所含元素的个数
LinkedList类中定义了两个构造函数:
public LinkedList() {        header.next = header.previous = header;    }//构造一个只有头节点的循环链表,前后引用分别指向节点本身 public LinkedList(Collection<? extends E> c) {    this();    addAll(c);    }//首先调用上面的构造函数构造一个空的循环链表,然后将集合参数中的元素添加到已经创建的循环链表中

上面的addAll()方法的内部实现:

public boolean addAll(Collection<? extends E> c) {        return addAll(size, c);    }public boolean addAll(int index, Collection<? extends E> c) {        if (index < 0 || index > size)//首先判断目前集合中所包含的节点数            throw new IndexOutOfBoundsException("Index: "+index+                                                ", Size: "+size);        Object[] a = c.toArray();//将给定的集合参数转换成数组        int numNew = a.length;        if (numNew==0)            return false;    modCount++;        Entry<E> successor = (index==size ? header : entry(index));        Entry<E> predecessor = successor.previous;    for (int i=0; i<numNew; i++) {            Entry<E> e = new Entry<E>((E)a[i], successor, predecessor);            predecessor.next = e;            predecessor = e;        }        successor.previous = predecessor;        size += numNew;        return true;    }

LinkedList中有两个add方法,其内部实现都是调用的一个叫addBefore的方法:

private Entry<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++;return newEntry;    }//这种增加单个节点的方式与数据结构中循环链表增加单个节点的方式是一样的,就像下图所示:
这是在头节点前面增加一个节点

删除节点的操作跟增加节点的操作相反。

另外就是替换某个节点set方法

    public E set(int index, E element) {        Entry<E> e = entry(index);获得指定节点        E oldVal = e.element;//返回指定节点原数据        e.element = element;//将指定节点数据更换成新数据        return oldVal;//最后返回原数据    }


0 0
原创粉丝点击