转载请以链接形式标明出处:
本文出自:103style的博客
base on jdk_1.8.0_77
目录
- 简介
LinkedList的变量介绍LinkedList的构造函数LinkedList的数据操作函数- 小结
- 参考文章
简介
LinkedList和ArrayList一样,都实现了List接口,但其内部的数据结构有本质的不同。LinkedList是基于 链表 实现的(通过名字也能区分开来),所以它的 插入和删除 操作比ArrayList更加高效。但也是由于其为基于链表的,所以 随机访问的效率 要比ArrayList差。
LinkedList继承自AbstractSequenceList,实现了List、Deque、Cloneable、java.io.Serializable接口。AbstractSequenceList提供了List接口骨干性的实现以减少实现List接口的复杂度,Deque接口定义了双端队列的操作。
在
LinkedList中除了本身自己的方法外,还提供了一些可以使其作为栈、队列或者双端队列的方法。这些方法可能彼此之间只是名字不同,以使得这些名字在特定的环境中显得更加合适。
LinkedList也是 fail-fast 的(前边提过很多次了)。
LinkedList的变量介绍
-
transient int size = 0;:链表长度 -
transient Node<E> first;:头节点 -
transient Node<E> last;:尾节点
LinkedList的构造函数
无参构造函数没做啥操作,有参的则是进行数据添加操作,下面会介绍。
public LinkedList() {
}
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
LinkedList的数据操作函数
node(int index):获取对应节点addFirst(E e)andaddLast(E e): 添加头尾节点getFirst()andgetLast(): 获取头尾节点remove()、removeFirst()andremoveLast():删除头尾节点remove(int index)andremove(Object o): 删除对象get(int index)andset(int index, E element):获取和设置对应节点peek()、peekFirst()andpeekLast():获取对应节点的值element():获取头节点的值poll()、pollFirst()andpollLast():返回对应节点,并从链表中删除offer(E e)、offerFirst(E e)andofferLast(E e):添加节点push(E e):插入一个节点到头部pop():删除头部一个节点
node(int index) 获取对应节点
- 根据索引的位置靠近头还是尾,靠近那头则从那头开始遍历查找。
Node<E> node(int 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;
}
}
addFirst(E e) and addLast(E e) 添加头尾节点
addFirst(E e)构建节点newNode,赋值first = newNode,如果之前的头节点f为空则将last设置为newNode,否则将f的prev节点为newNode.addLast(E e)构建节点newNode,赋值last = newNode,如果之前的尾节点l为空则将first设置为newNode,否则将l的next节点为newNode.
public void addFirst(E e) {
linkFirst(e);
}
private void linkFirst(E e) {
final Node<E> f = first;
final Node<E> newNode = new Node<>(null, e, f);
first = newNode;
if (f == null)
last = newNode;
else
f.prev = newNode;
size++;
modCount++;
}
public void addLast(E e) {
linkLast(e);
}
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++;
}
element() 、getFirst() and getLast() 获取头尾节点
- 如果头尾节点为空则会抛出异常
NoSuchElementException,否则返回对应的item值。
public E element() {
return getFirst();
}
public E getFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return f.item;
}
public E getLast() {
final Node<E> l = last;
if (l == null)
throw new NoSuchElementException();
return l.item;
}
remove()、removeFirst() and removeLast() 删除头尾节点
remove()即为删除头节点- 删除即为更新节点的
prev和next节点。
public E remove() {
return removeFirst();
}
public E removeFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return unlinkFirst(f);
}
public E removeLast() {
final Node<E> l = last;
if (l == null)
throw new NoSuchElementException();
return unlinkLast(l);
}
private E unlinkFirst(Node<E> f) {
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
next.prev = null;
size--;
modCount++;
return element;
}
private E unlinkLast(Node<E> l) {
final E element = l.item;
final Node<E> prev = l.prev;
l.item = null;
l.prev = null; // help GC
last = prev;
if (prev == null)
first = null;
else
prev.next = null;
size--;
modCount++;
return element;
}
remove(int index) and remove(Object o) 删除对象
remove(int index)会检查下标,然后删除节点remove(Object o)则会更具o是否为null用=或equals找到对应的节点,再删除。删除成功会返回ture,失败则为false.
public E remove(int index) {
checkElementIndex(index);
return unlink(node(index));
}
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;
}
get(int index) and set(int index, E element)
- 都先检查索引,
get直接返回节点的值,set则修改节点的值并返回之前的旧值。
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
public E set(int index, E element) {
checkElementIndex(index);
Node<E> x = node(index);
E oldVal = x.item;
x.item = element;
return oldVal;
}
peek()、peekFirst() and peekLast()
- 返回头尾节点的值,如果节点为
null再返回null.
public E peek() {
final Node<E> f = first;
return (f == null) ? null : f.item;
}
public E peekFirst() {
final Node<E> f = first;
return (f == null) ? null : f.item;
}
public E peekLast() {
final Node<E> l = last;
return (l == null) ? null : l.item;
}
poll()、pollFirst() and pollLast()
- 返回头尾节点,并总链表中移除
public E poll() {
final Node<E> f = first;
return (f == null) ? null : unlinkFirst(f);
}
public E pollFirst() {
final Node<E> f = first;
return (f == null) ? null : unlinkFirst(f);
}
public E pollLast() {
final Node<E> l = last;
return (l == null) ? null : unlinkLast(l);
}
offer(E e)、offerFirst(E e) and offerLast(E e)
- 添加节点
public boolean offer(E e) {
return add(e);
}
public boolean offerFirst(E e) {
addFirst(e);
return true;
}
public boolean offerLast(E e) {
addLast(e);
return true;
}
push(E e)
- 插入一个节点到头部
public void push(E e) {
addFirst(e);
}
pop()
- 删除头节点
public E pop() {
return removeFirst();
}
小结
- LinkedList查找类似二分查找, 靠近那边则从那边开始查。
参考文章
以上

本文介绍了Java中LinkedList的相关知识。它基于链表实现,插入和删除操作比其他一些结构更高效,但随机访问效率较差。文章详细介绍了其变量、构造函数,还列举了多种数据操作函数,如获取、添加、删除节点等,最后指出其查找类似二分查找。
439

被折叠的 条评论
为什么被折叠?



