参考文章:JCFInternals
环境:JDK1.9
介绍:
LinkedList同时实现了List接口和Deque接口,也就是说它既可以看作一个顺序容器,又可以看作一个队列(Queue),同时又可以看作一个栈(Stack),LinkedList底层通过双向链表实现,允许放入 null,未实现同步。
实现功能:
- size():得到当前集合元素个数
- isEmpty():判断集合是否为空
- get(int index):获得指定位置集合
- set(int index, T element):将指定位置集合设置为指定值
- add(T element):向集合添加一个元素
- add(int index, T element):向集合指定下标添加指定元素
- remove(int index):移除指定下标的元素
- remove(Object o):移除集合中第一次出现的指定元素
代码:
public class MyLinkedList<T> {
int size;
// 链表的第一个元素
Node<T> first;
// 链表的最后一个元素
Node<T> last;
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
// 定义链表结点
private static class Node<T> {
T item;
Node<T> prev;
Node<T> next;
public Node(Node<T> prev, T item, Node<T> next) {
this.item = item;
this.prev = prev;
this.next = next;
}
}
public boolean add(T element) {
// 找到末尾指针
final Node<T> l = last;
final Node<T> newNode = new Node(l, element, null);
last = newNode;
// 如果当前链表为空,则 newNode 为第一个结点
if (l == null) {
first = newNode;
} else {
l.next = newNode;
}
size++;
return true;
}
public void add(int index, T element) {
// 范围检查
checkPositionIndex(index);
// 如果是最后一个插入
if (index == size) {
add(element);
} else {
// 找到 index 位置的链表
final Node<T> cur = node(index);
// 修改引用
// 1. 要插入的新结点是 newNode
// 2. newNode 的前一结点是 pred
// 3. newNode 的后一结点是 cur
final Node<T> pred = cur.prev;
final Node<T> newNode = new Node(pred, element, cur);
cur.prev = newNode;
if (pred == null) {
first = newNode;
} else {
pred.next = newNode;
}
size++;
}
}
public boolean remove(Object o) {
if (o == null) {
for (Node<T> x = first; x != null; x = x.next) {
if (x.item == null) {
// 删除该结点
unlink(x);
return true;
}
}
} else {
for (Node<T> x = first; x != null; x = x.next) {
if (x.item.equals(o)) {
// 删除该结点
unlink(x);
return true;
}
}
}
return false;
}
public T remove(int index) {
// 范围检查
checkPositionIndex(index);
return unlink(node(index));
}
public T get(int index) {
// 范围检查
checkPositionIndex(index);
return node(index).item;
}
public T set(int index, T element) {
// 范围检查
checkPositionIndex(index);
Node<T> x = node(index);
T oldVal = x.item;
x.item = element;
return oldVal;
}
private T unlink(Node<T> x) {
final T element = x.item;
final Node<T> prev = x.prev;
final Node<T> next = x.next;
// 修改前一结点的指针
if (prev == null) {
first = next;
} else {
prev.next = next;
x.prev = null;
}
// 修改后一结点的指针
if (next == null) {
last = prev;
} else {
next.prev = prev;
x.next = null;
}
x.item = null;
size--;
return element;
}
private Node<T> node(int index) {
// 前一半
if (index < (size >> 1)) {
Node<T> x = first;
for (int i = 0; i < index; i++) {
x = x.next;
}
return x;
} else {
Node<T> x = last;
for (int i = size - 1; i > index; i--) {
x = x.prev;
}
return x;
}
}
private boolean checkPositionIndex(int index) {
if (index < 0 || index > size) {
throw new RuntimeException("下标越界!");
}
return true;
}
}