package com.mybatis.controller;
import java.util.*;
import java.util.function.Consumer;
/**
* @创建人 yfc
* @创建时间 2019-09-19 18:09
* @描述 线程不安全的链表组成,双向链表,移动速度慢,插入速度快,查询效率低(采用折半方法,判断当前index是接近头部还是尾部,但是当数据量大的时候,效率依旧低)
*/
public class YLinkedList<E> extends AbstractSequentialList<E> implements List<E> {
transient int size = 0;
//指向第一个节点的指针
transient Node<E> first;
//指向最后一个节点的指针
transient Node<E> last;
public int size() {
return size;
}
//新增节点
public boolean add(E e) {
linkLast(e);
return true;
}
/**
* 链接E作为最后一个元素(尾插法,从尾部开始添加,hashmap中链表采用的是头插法)。
*/
void linkLast(E e) {
//最后一个节点
final Node<E> l = last;
//当前节点(上一个节点为最后节点,下一个节点为null)
final Node<E> newNode = new Node<>(l, e, null);
//最后一个节点变为新增的这个节点
last = newNode;
//判断之前的尾节点是否为空,如果为空,第一个节点也为新增的节点,不为空,则为之前的尾节点加上下一个节点指针
if (l == null)
first = newNode;
else
l.next = newNode;
//链表长度加1
size++;
modCount++;
}
/**
* 在此列表中的指定位置插入指定元素。将当前位于该位置的元素(如果有)和任何后续元素向右移动(在其索引中添加一个元素)
* element:新插入的元素
*/
public void add(int index, E element) {
checkPositionIndex(index);
//判断当前位置是不是最后一个
if (index == size)
linkLast(element);
else
//index位置上插入新的值
linkBefore(element, node(index));
}
/**
* 返回指定元素索引处的(非空)节点。
*/
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;
}
}
/**
* 在非空节点成功之前插入元素e.
*/
void linkBefore(E e, Node<E> succ) {
// assert succ != null;
final Node<E> pred = succ.prev;
//new一个新的节点,在index位置上插入新的节点,并将当前节点向后移一位
final Node<E> newNode = new Node<>(pred, e, succ);
succ.prev = newNode;
if (pred == null)
first = newNode;
else
pred.next = newNode;
size++;
modCount++;
}
private void checkPositionIndex(int index) {
if (!isPositionIndex(index))
throw new IndexOutOfBoundsException("索引下标越界");
}
/**
* 返回此列表中指定位置的元素。
*/
public E get(int index) {
//检查索引是否存在
checkElementIndex(index);
return node(index).item;
}
/**
* 指示参数是否为现有元素的索引
*/
private void checkElementIndex(int index) {
if (!isElementIndex(index))
throw new IndexOutOfBoundsException("索引下标越界");
}
/**
* 指示参数是否为有效索引---(ps:这个方法同isPositionIndex功能一样,不知道JDK8为啥有这波操作)
*/
private boolean isElementIndex(int index) {
return index >= 0 && index < size;
}
/**
* 判断当前索引是否有效
*/
private boolean isPositionIndex(int index) {
return index >= 0 && index <= size;
}
/**
* 返回最后一个元素
*/
public E getLast() {
final Node<E> l = last;
if (l == null)
throw new NoSuchElementException();
return l.item;
}
/**
* 删除元素
*/
public E remove(int index) {
checkElementIndex(index);
return unlink(node(index));
}
/**
* 解除元素的关联
*/
E unlink(Node<E> x) {
// assert x != null;
final E element = x.item;
//当前元素的下一个元素
final Node<E> next = x.next;
//当前元素的前一个元素
final Node<E> prev = x.prev;
//当前元素的前一个如果为空,说明当前是第一个元素,去除第一个元素,第一个元素的下一个元素向前移动
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--;
modCount++;
return element;
}
//将链表转数组
public Object[] toArray() {
//定义一个size大的数组
Object[] result = new Object[size];
int i = 0;
for (Node<E> x = first; x != null; x = x.next)
result[i++] = x.item;
return result;
}
//迭代器
public ListIterator<E> listIterator(int index) {
//检查index是否有效
checkPositionIndex(index);
return new ListItr(index);
}
//内部类
private class ListItr implements ListIterator<E> {
private Node<E> lastReturned;
private Node<E> next;
private int nextIndex;
private int expectedModCount = modCount;
ListItr(int index) {
// 根据index定位到当前元素
next = (index == size) ? null : node(index);
nextIndex = index;
}
//eg:size 4,nextIndex 3 ()
public boolean hasNext() {
return nextIndex < size;
}
public E next() {
checkForComodification();
if (!hasNext())
throw new NoSuchElementException();
lastReturned = next;
next = next.next;
nextIndex++;
return lastReturned.item;
}
public boolean hasPrevious() {
return nextIndex > 0;
}
public E previous() {
checkForComodification();
if (!hasPrevious())
throw new NoSuchElementException();
lastReturned = next = (next == null) ? last : next.prev;
nextIndex--;
return lastReturned.item;
}
public int nextIndex() {
return nextIndex;
}
public int previousIndex() {
return nextIndex - 1;
}
public void remove() {
checkForComodification();
if (lastReturned == null)
throw new IllegalStateException();
Node<E> lastNext = lastReturned.next;
//unlink(lastReturned);
if (next == lastReturned)
next = lastNext;
else
nextIndex--;
lastReturned = null;
expectedModCount++;
}
public void set(E e) {
if (lastReturned == null)
throw new IllegalStateException();
checkForComodification();
lastReturned.item = e;
}
public void add(E e) {
checkForComodification();
lastReturned = null;
if (next == null)
linkLast(e);
else
linkBefore(e, next);
nextIndex++;
expectedModCount++;
}
public void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (modCount == expectedModCount && nextIndex < size) {
action.accept(next.item);
lastReturned = next;
next = next.next;
nextIndex++;
}
checkForComodification();
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
//内部类
private static class Node<E> {
//当前节点
E item;
//下一个节点
YLinkedList.Node<E> next;
//前一个节点
YLinkedList.Node<E> prev;
Node(YLinkedList.Node<E> prev, E element, YLinkedList.Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
}