1.LinkedList是一个实现双向链表的集合类,并且实现了list接口和deque接口,也就是说,LinkedList既可以当成双向链表使用,还可以当作栈使用,也可以当作队列使用(Deque代表双端队列,既有队列的特征又有栈的特征。),定义的源码如下:
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
transient int size = 0;
};
我们看到有这样一个关键词:transient,这个关键词是让被修饰的变量不被序列化,因为我们把敏感的信息用这个关键词修饰,防止序列化然后反序列化被人盗窃。例如:密码,银行卡号等敏感信息。
2.LinkedList实现了list的所有接口方法,并且可以存储null值。
3.LinkedList是线程不安全的,如果我们想让它安全可以这样定义一个LinkedList的对象:List list = Collections.synchronizedList(new LinkedList(...));
4.当迭代器创建之后,当链表的结构被改变,除了迭代器本身自己的remove和add方法除外,那么该对象调用的迭代器方法将返回fail-fast;
5.当我们使用add(int index,E element)方法时,看它内部程序如何工作的。源码如下:
public void add(int index, E element) {
checkPositionIndex(index);//1
if (index == size)
linkLast(element);//2
else
linkBefore(element, node(index));//3
}
Node<E> node(int index)
// assert isElementIndex(index);
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
解析如下:第一条语句是检查index变量大小是否符合要求,如果大小和链表的长度相同,那么就直接用linkLast算法,直接在最后添加,这样减少了查找index 索引的开销,否则的话就在要求的节点前添加元素,这里的node(index)是查找目的节点的函数,然后最后执行linkBefore函数开始添加元素。
linkBefore函数源码如下:
{//4void linkBefore(E e, Node<E> succ) {
// assert succ != null;
final Node<E> pred = succ.prev;
final Node<E> newNode = new Node<>(pred, e, succ);
succ.prev = newNode;
if (pred == null)
first = newNode;
else
pred.next = newNode;
size++;
modCount++;
}
我们看出来,查找索引的开销比较大,如果直接类似于addFisrt(E e)那么就很快了。其他的成员函数时间复杂度以此类推就可以了。