LinkedList
LinkedList 的简介
LinkedList是基于链表实现的,LinkedList是一种双向链表,双向链表我认为有两点含义:
1、链表中任意一个存储单元都可以通过向前或者向后寻址的方式获取到其前一个存储单元和其后一个存储单元
2、链表的尾节点的后一个节点是链表的头结点,链表的头结点的前一个节点是链表的尾节点
LinkedList的基本存储单元,它是LinkedList中的一个内部类:
private static class Entry<E> {
E element;
Entry<E> next;
Entry<E> previous;
...
}
看到LinkedList的Entry中的"E element",就是它真正存储的数据。"Entry next"和"Entry previous"表示的就是这个存储单元的前一个存储单元的引用地址和后一个存储单元的引用地址。用图表示就是:
添加元素
1 public static void main(String[] args)
2 {
3 List<String> list = new LinkedList<String>();
4 list.add("111");
5 list.add("222");
6 }
逐行分析main函数中的三行代码是如何执行的,首先是第3行,看一下LinkedList的源码:
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
private transient Entry<E> header = new Entry<E>(null, null, null);
private transient int size = 0;
/**
* Constructs an empty list.
*/
public LinkedList() {
header.next = header.previous = header;
}
...
}
看到,new了一个Entry出来名为header,Entry里面的previous、element、next都为null,执行构造函数的时候,将previous和next的值都设置为header的引用地址,还是用画图的方式表示。32位JDK的字长为4个字节,而目前64位的JDK一般采用的也是4字长,所以就以4个字长为单位。header引用地址的字长就是4个字节,假设是0x00000000,那么执行完"List list = new LinkedList()"之后可以这么表示:
接着看第4行add一个字符串"111"做了什么:
1 public boolean add(E e) {
2 addBefore(e, header);
3 return true;
4 }
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;
}
第2行new了一个Entry出来,可能不太好理解,根据Entry的构造函数,我把这句话"翻译"一下,可能就好理解了:
1、newEntry.element = e;
2、newEntry.next = header.next;
3、newEntry.previous = header.p