LInkedList集合底层
LinkedList集合底层是双向链表,元素同样也有下标,但内存地址不连续,故检索速度依然慢。(ArrayList集合检索快是因为使用了数组,内存地址连续。)
LinkedList集合内存分析
1、创建一个对象
首先看到以下代码:
LinkedList l=new LinkedList();
l.add("a");
l.add("b");
l.add("c");
首先,执行LinkedList l=new LinkedList();执行到的源码如下:
transient int size = 0;
transient Node<E> first;
transient Node<E> last;
public LinkedList() {
}
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;
}
}
其中,Node是一个内部类,创建这两个对象后在堆内存中开辟两块地址空间。
此时内存图如下
2、添加集合的第一个元素
执行add方法,源代码如下:
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 = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
调用了LinkLast方法,LinkLast方法创建了一个Node指向last,而last原本为null(last的地址赋给l,故l变为null),然后又创建了一个newNode,地址为0x23(图中简写为nn),让last指向nn(last的值变为0x23)。nn的pre指向了l,即为null,next为null。进入if语句后,l为空,故first又指向nn,完成了集合在空的状态下添加第一个元素
此时内存如下:
3、添加集合的非第一个元素。
代码依然是上面那段。此时,last为0x23,l指向last,故l变为0x23,
然后执行final Node newNode = new Node<>(l, e, null);,,nn的地址变为0x45,然后让l指向nn的pre,内存如下
再执行last = newNode;,last指向nn,内存如下
最后,进入if语句执行l.next = newNode;,l.next即元素为a的nn.next指向新建的元素味b的nn.next,此时,内存如下
每次执行玩add方法后,栈方法区中的 LinkLast方法栈帧会弹栈,故内存如下:
执行第三次add方法过程与第二次类似。
本文章图片来自动力结点。