1、LinkList的结构如下
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;
//节点的结构
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;
}
}
}
由上面可知,LinkList是一个双向列表结构
2、构造函数
//空的构造函数
public LinkedList() {
}
//传入集合的构造函数
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
和ArrayList对比可以发现,LinkedList没有容量的限制,不需要指定集合的大小。
3、元素添加
//1、添加单个元素。在最后一个元素后面添加
public boolean add(E e) {
linkLast(e);
return true;
}
//2、添加元素到指定位置
public void add(int index, E element) {
checkPositionIndex(index);
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
//3、添加到头元素
public void addFirst(E e) {
linkFirst(e);
}
//4、添加到尾元素
public void addLast(E e) {
linkLast(e);
}
//5、添加到集合
public boolean addAll(Collection<? extends E> c) {
return addAll(size, c);
}
主要调用了linkFirst和linkLast这两个方法
1) linkLast(E e)
void linkLast(E e) {
final Node<E> l = last;
//1、创建一个Node,prev指向last,netx为空
final Node<E> newNode = new Node<>(l, e, null);
//2、last节点为新加的节点
last = newNode;
//3、如果last节点为空,则说明新增加的节点newNode是第一个元素。
//否则,将原来的last节点的next复制为新的节点
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
4、删除操作
删除操作,总结起来就是unlink方法
E unlink(Node<E> x) {
//获取当前节点的元素,前一个节点和后一个节点
final E element = x.item;
final Node<E> next = x.next;
final Node<E> prev = x.prev;
//如果要删除节点的前一个节点为空,则说明要删除的元素就是第一个元素。
if (prev == null) {
//将该元素的下一个节点赋值给first节点
first = next;
} else {
//如果要删除节点的前一个节点不为空。则将他前一个节点的next赋值为当前节点的next
prev.next = next;
x.prev = null;
}
//如果要删除的元素next为空,则说明要删除的元素是最后一个元素。
if (next == null) {
//将该元素的前一个节点赋值给last
last = prev;
} else {
next.prev = prev;
x.next = null;
}
//将当前元素置为null
x.item = null;
size--;
modCount++;
return element;
}
5、修改元素
public E set(int index, E element) {
checkElementIndex(index);
//获取到当前元素
Node<E> x = node(index);
//老的元素
E oldVal = x.item;
//将新的元素赋值给x.item
x.item = element;
return oldVal;
}
6、查询元素
1) 按index查询元素。(查询第几个元素)
Node<E> node(int index) {
//如果index在整个链表的前半部分,在从first往后查询
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
}
//如果index在整个链表的后半部分,在从last往前查询
else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
2) 按照对象查询元素的位置(index)
public int indexOf(Object o) {
//从前往后遍历
int index = 0;
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null)
return index;
index++;
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item))
return index;
index++;
}
}
return -1;
}
ArrayList和LinkedList使用对比: Java ArrayList,LinkedList使用
原文:https://www.cnblogs.com/linlf03/p/12621283.html