添加元素源码
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
// 头指针不为空 最后一个元素的next 指向 新元素
l.next = newNode;
size++;
modCount++;
}
node数据结构
private static class Node<E> {
// 存放的数据
E item;
Node<E> next; // 上一个元素
Node<E> prev; // 下一个元素 新的元素永远是最后一个元素
// 所以没有next =null, prev =last
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
查找元素
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;
}
}
数据结构图
作为队列的性质
private void linkFirst(E e)
{
// 1、先保留头指针
final Node<E> f = first;
// 2、创建新节点 新元素的next -->f 新元素的上一个没有null
final Node<E> newNode = new Node<>(null, e, f);
// 3、头指针指向-新节点
first = newNode;
if (f == null)
//头指针不在 尾指针 和 头指针 都指向第一个元素
last = newNode;
else
// 当添加第2个元素的时候 头指针的上一个元素指向新元素
f.prev = newNode;
// 元素个数+1
size++;
modCount++;
}
队列offer源码
Queue<String> q1 = new LinkedList<>();
// 其实就是调用了add();方法
q1.offer("aa");
q1.offer("bb");
q1.offer("cc");
// 判断队列中是否有元素
while (q1.peek() != null)
{
System.out.println(q1.poll());
}
// 堆栈
Deque<String> list = new LinkedList();
// 其实就是调用了linkFirst 方法
list.push("1111");
list.push("2222");
list.push("3333");
while (list.peek() !=null)
{
String fd = list.poll();
System.out.println(fd);
}
peek 源码
public E peek()
{
//其实就是 获取头指针 指向的元素
final Node<E> f = first;
return (f == null) ? null : f.item;
}
poll源码
public E poll()
{
final Node<E> f = first;
return (f == null) ? null : unlinkFirst(f);
}
unlinkFirst 源码
private E unlinkFirst(Node<E> f)
{
// 出队源码 永远出first指针指向的第一个元素
// assert f == first && f != null;
final E element = f.item;
final Node<E> next = f.next;
f.item = null;
f.next = null; // help GC
// 把头指针指向 第一个元素的下个地址
first = next;
if (next == null)
last = null;
else
// 因为已经出队了 出队元素指向上一个元素的指针=null Help GC
next.prev = null;
// 数量--1
size--;
// 修改次数+1
modCount++;
return element;
}
出队 入队 判断是否有元素 都有2个方法 方法的区分是啥?
在尾部添加元素 (add, offer): add()会在长度不够时抛出异常:IllegalStateException; offer()则不会,只返回false
查看头部元素 (element, peek),返回头部元素,但不改变队列 element()会在没元素时抛出异常:NoSuchElementException; peek()返回null;
删除头部元素 (remove, poll),返回头部元素,并且从队列中删除 remove()会在没元素时抛出异常:NoSuchElementException; poll()返回null;