1, 比较
LinkedList和ArrayList最本质的区别:
LinkedList存贮的是一个双向链表,而ArrayList里面存贮的是数组。
所以在一般情况下,
1,对于随机访问, ArrayList性能要高
2,对于增加删除操作, LinkedList性能要高
3,对于查找等操作,两者性能相差无几。
杂七杂八的接口太多,直接按照方法来论述。
2, LinkedList
首先看看LinkedList的构造方法
2.1, 构造方法
LinkedList一共有2个构造方法,从最简单的开始分析,
public LinkedList() {
voidLink = new Link<E>(null, null, null);
voidLink.previous = voidLink;
voidLink.next = voidLink;
}
voidLink 是实际对象, Link是什么鬼呢?
Link是LinkedList的内部类。
transient Link<E> voidLink;
private static final class Link<ET> {
ET data;
Link<ET> previous, next;
Link(ET o, Link<ET> p, Link<ET> n) {
data = o;
previous = p;
next = n;
}
}
Link实际上就是一个双向链表,包含一个范型对象和2个指针,2个指针分别指向前一个和后一个链表。
刚开始构造时,链表里面的对象都是空的。
另外一个构造方法首先调用这个构造方法然后调用addall方法将集合添加到链表中,在此就不多论述了。
LinkedList中有三个变量,
private static final long serialVersionUID = 876323262645176354L; // 系列化
transient int size = 0; // 链表的长度
transient Link<E> voidLink; // 链表的标志
在构造方法中,voidLink前后指针都指向自己。
2.2, add方法
Add方法比较多,共有8个,本质都是一样的,看一个源码就可以了
@Override
public void add(int location, E object) {
if (location >= 0 && location <= size) {
Link<E> link = voidLink;
if (location < (size / 2)) {
for (int i = 0; i <= location; i++) {
link = link.next;
}
} else {
for (int i = size; i > location; i--) {
link = link.previous;
}
}
Link<E> previous = link.previous;
Link<E> newLink = new Link<E>(object, previous, link);
previous.next = newLink;
link.previous = newLink;
size++;
modCount++;
} else {
throw new IndexOutOfBoundsException();
}
}
因为是双向链表,所以可以从2个方向遍历,添加时可以根据元素添加的位置选择一个方向,可以稍微提高效率。
其他的链表操作也很简单,看代码就可以一目了然,在此就不多论述了。