一、类说明
从LinkedList这个类名我们就猜出,这个List内部可能是由【链表】来实现,我们后面来验证一下。
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, Serializable {
transient int size;
//指向first节点
transient LinkedList.Node<E> first;
//指向last节点
transient LinkedList.Node<E> last;
}
它实现了Deque接口,可以知道,LinkedList也可以作为【队列】来进行使用。
同时也实现了Serializable接口,说明可以对它进行序列化,反序列化来传递,获取数据等
LinkedList的成员变量:
int size表明:List有多少个元素
Node类型的first变量:指向头节点的变量 (用C,C++解释称之为指针)
Node类型的last变量:指向最后节点的变量
Node类源码:
private static class Node<E> {
E item;
LinkedList.Node<E> next;
LinkedList.Node<E> prev;
Node(LinkedList.Node<E> var1, E var2, LinkedList.Node<E> var3) {
this.item = var2;
this.next = var3;
this.prev = var1;
}
}
这是一个LinkedList的内部类,
一个泛型的item变量,用来存储数据
next:指向下一个节点的next指针
prev:指向前一个节点的prev指针
至此我们其实就可以得出结论,LinkedList内部就是由【链表】的形式实现。
它并没有用数组来存储数据元素,而是由一个个【Node类型的节点】来存储数据,然后每个Node节点通过指向前后节点的next和prev指针将整个List串联起来。
通过简单图来看看ArrayList和LinkedList的基本区别:
正是这样的区别,从而导致了两者不同的效率问题:
如果对一个ArrayList频繁的增加数据,那么内部的数组就会不断扩容创建新的数组,然后把旧的数据复制到新数组返回。
插入数据或者删除其中一个数据,又要把所有数据后移或者前移。
这样的操作效率很低下,为了一个数据处理了其他数据。
LinkedList不同,插入只需要将要插入位置的前节点的next指针指向新的数据节点(如下图插入工作的2),将插入节点的prev指向前节点(如1处),将next指向下一个节点(如3处),将之前的后节点的prev指针指向插入的新节点(如4处)。