Java 中的 LinkedList 相对于 ArrayList 使用的频率比较小,它实现了java.util.List 接口, 虽然它与ArrayList都实现了该接口但是内部实现差异非常大,LinkedList内部是用链表实现的,这就决定了LinkedList的随机访问操作非常低效,时间复杂度为O(n);单次插入效率为O(1), 但是每插入一次都要伴随着一次查找,所以单次插入效率同样低下,但是如果用ListIterator连续做插入操作则效率很高。在头部和尾部做访问和插入操作效率都很高,基于这个原因可以用来实现队列,系统实现的LinkedList是实现了 Queue 接口的,如果需要使用队列可以选择LinkedList, 以下代码是一个简单实现,作为练习只实现了最基本的部分。
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* @ClassName: MyLinkedList1
* @Description: 简易实现LinkedList
* @author: he.li
* @service
* @version:V1.0.0
* @param <T>
*
*/
public class MyLinkedList1<T> implements Iterable<T> {
//头结点
private Node<T> beginNode = null;
//尾节点
private Node<T> endNode = null;
//有效元素数量
private int theSize;
//并发控制计数
private int modCount;
public MyLinkedList1() {
doClear();
}
//初始化头尾节点
private void doClear() {
beginNode = new Node<T>(null, null, null);
endNode = new Node<T>(null, beginNode, null);
beginNode.next = endNode;
modCount++;
}
public int size() {
return theSize;
}
public boolean isEmpty() {
return theSize == 0;
}
public T get(int idx) {
return getNode(idx).data;
}
public void add(T data) {
add(theSize, data);
}
public void add(int idx, T data) {
Node<T> node = getNode(idx, 0, theSize);
Node<T> newNode = new Node<T>(data, node.prev, node);
node.prev = node.prev.next = newNode;
theSize++;
modCount++;
}
public T remove(int idx) {
Node<T> node = getNode(idx);
return remove(node);
}
private T remove(Node<T> node) {
node.prev.next = node.next;
node.next.prev = node.prev;
theSize--;
modCount++;
return node.data;
}
public void set(int idx, T data) {
Node<T> node = getNode(idx);
node.data = data;
modCount++;
}
private Node<T> getNode(int idx) {
return getNode(idx, 0, theSize - 1);
}
//获取指定下标节点
private Node<T> getNode(int idx, int lower, int upper) {
if (idx < lower || idx > upper) {
throw new IndexOutOfBoundsException();
}
Node<T> node = null;
if (idx < lower / 2) {
node = beginNode.next;
for (int i = 0; i < idx; i++) {
node = node.next;
}
} else {
node = endNode;
for (int i = theSize; i > idx; i--) {
node = node.prev;
}
}
return node;
}
//内部节点类
private static class Node<T> {
public T data;
public Node<T> prev;
public Node<T> next;
public Node(T data, Node<T> prev, Node<T> next) {
this.data = data;
this.prev = prev;
this.next = next;
}
}
//获取迭代器
@Override
public Iterator<T> iterator() {
return new MyLinkedListIterator();
}
@Override
public String toString() {
if (theSize == 0) {
return "[]";
}
StringBuilder sb = new StringBuilder("[");
Iterator<T> it = iterator();
for (;;) {
T next = it.next();
sb.append(next);
if (!it.hasNext()) {
return sb.append("]").toString();
}
sb.append(", ");
}
}
//内部类迭代器
private class MyLinkedListIterator implements Iterator<T> {
//当前所在节点
private Node<T> current;
private int expectModCount = modCount;
private boolean toOkRemove = false;
public MyLinkedListIterator() {
current = beginNode.next;
}
@Override
public boolean hasNext() {
//当前迭代指针指向endNode则代表到末尾
return current != endNode;
}
@Override
public T next() {
//迭代期间修改了容器,抛出异常
if (expectModCount != modCount) {
throw new ConcurrentModificationException();
}
if (!hasNext()) {
throw new NoSuchElementException();
}
T data = current.data;
current = current.next;
toOkRemove = true;
return data;
}
public void remove() {
if (expectModCount != modCount) {
throw new ConcurrentModificationException();
}
if (!toOkRemove) {
throw new IllegalStateException();
}
MyLinkedList1.this.remove(current.prev);
expectModCount = modCount;
toOkRemove = false;
}
}
}