初识
LinkedList是以链表实现,插入、删除时只需要改变前后两个节点指向就行。
特点
- 双向链表实现,所有在添加/删除元素的时候只会影响前后两个节点
- 只能顺序遍历,无法按照索引获得元素,因此查询的效率不高
- 允许元素为null
- 没有固定的容量,不需要扩容
- 所有指定位置的操作都是逐一遍历
结构
内部结构
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable{
//容量
transient int size = 0;
//头部节点
transient Node<E> first;
//尾部节点
transient Node<E> last;
protected transient int modCount = 0;
}
//Node结构 双向节点
private static class Node<E> {
E item; //本元素
Node<E> next; //后节点
Node<E> prev;//前一个节点
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
LinkedList中的方法
起始和结束位置的元素所指向的last和pre都是null
- 初始化
public LinkedList(){}
- add()方法
public boolean add(E e){
//默认每次添加元素都是追加到最后
linkLast(e);
return true;
}
//具体的添加元素操作
void linkLast(E e) {
//将最后一个元素拿出来
final Node<E> l = last;
//初始化添加的新元素Node
final Node<E> newNode = new Node<>(l, e, null);
//将最新添加的元素赋值为最后元素
last = newNode;
//判断如果是第一次添加元素,则第一个元素也就是新添加的元素
if (l == null)
first = newNode;
else
//如果不行,则将之前最后元素的下一个元素设置为新添加的元素
l.next = newNode;
size++;
modCount++;
}
- remove()方法
public boolean remove(Object o) {
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
//如果是空的话
if (x.item == null) {
unlink(x);
return true;
}
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
//如果不是空
if (o.equals(x.item)) {
unlink(x);
return true;
}
}
}
return false;
}