LinkedList是一种基于链表实现的集合类,也是经常使用到的集合。其特性归纳如下:
特性 | 值 |
---|---|
是否顺序存储 | 顺序 |
是否可重复存储 | 可以 |
是否可存储null | 可以 |
是否线程安全 | 非线程安全 |
LinkedList的属性
首先列举一下ArrayList主要属性,方便大家理解和本文的说明:
属性 | 说明 |
---|---|
first | 链表的头部 |
last | 链表的尾部 |
size | 存储元素的总数 |
新建 LinkedList
public LinkedList() {
}
没有任何处理
add方法
public void add(int index, E element) {
checkPositionIndex(index);
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
先看下第3行代码,如果索引值和当前List的大小一样的话,就添加到末尾,这里和add(E element)是一样的。否则执行到第5行,先取出目前指定索引存放的元素
void 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++;
}
对于pre和next重新指定一下即可,所以LinkedList的add(int index, E element)效率优于ArrzyList,时间复杂度是O(1)。
get方法
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
看下第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的大小来判断,如果index小于长度的1/2,也就是index比较靠前就从链表头部开始遍历,否则从尾部开始比遍历。LinkedList的get方法要比ArrayList的慢。
set方法
public E set(int index, E element) {
checkElementIndex(index);
Node<E> x = node(index);
E oldVal = x.item;
x.item = element;
return oldVal;
}
是取出目前的元素,在替换成新的元素,效率和ArrayList的相似。
总结
1.LinkedList是基于链表实现的集合
2.LinkedList也是非线程安全的
3.remove(int index),add(int index, E element)的效率LinkedList比ArrayList更好,而get(int index)的效率则相反。因此需要看具体情况来使用这2种List。