作为一个稀有的Java妹子,所写的所有博客都只是当作自己的笔记,留下证据自己之前是有用心学习的~哈哈哈哈(如果有不对的地方,也请大家指出,不要悄悄咪咪的不告诉我)
LinkedList
LinkedList也是有序集合之一,这里的有序是指放入集合的顺序,不是指按照元素大小排序的。与同样是有序集合ArrayList相比,两者有什么相同点和区别呢?
ArrayList | LinkedList |
---|---|
底层是数组结构 | 底层是链表结构 |
适合多查询,少插入删除元素 | 适合多插入,删除元素,少查询操作 |
有序 | 有序 |
成员变量
transient int size = 0;
//为了方便取出LinkedList的第一个元素
transient Node<E> first;
//为了方便取出LinkedList的最后一个元素
transient Node<E> last;
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底层是链表结构,每个元素都是一个Node,里面包括本身元素的值和指向前后元素的指针,示意图如下:
常用方法
方法名 | 作用 |
---|---|
getFirst() | 获取第一个元素 |
peek() | 获取第一个元素 |
getLast() | 获取最后一个元素 |
removeFirst() | 移除第一个元素 |
poll() | 移除第一个元素 |
removeLast() | 移除最后一个元素 |
addFirst(E e) | 在集合的头部插入元素 |
push(E e) | 在集合的头部插入元素 |
addLast(E e) | 在集合的尾部添加元素 |
看一下添加元素的源码
//在集合最后添加元素
public boolean add(E e) {
linkLast(e);
return true;
}
void linkLast(E e) {
//获取目前集合的最后一个元素
final Node<E> l = last;
//创建新添加的元素
final Node<E> newNode = new Node<>(l, e, null);
//将新添加的元素设为last
last = newNode;
if (l == null)
first = newNode;
else
//将集合之前的最后一个元素的next指针指向新添加的元素
l.next = newNode;
size++;
modCount++;
}
//在指定位置插入元素
public void add(int index, E element) {
checkPositionIndex(index);
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
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++;
}
从源码可以看出,linkedlist没有扩容机制,因为底层是链表,插入元素时,就是改变prev和next指针,如下图需要在集合元素aa和bb之间插入11,其实就是断开之前aa和bb之间连接,然后使得aa的next指针指向11,11的next指向bb,bb的prev指向11。