LinkedList集合,是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。LinkedList 是非同步的。
LinkedList是通过节点直接彼此连接来实现的。每一个节点都包含前一个节点的引用,后一个节点的引用和节点存储的值。当一个新节点插入时,只需要修改其中保持先后关系的节点的引用即可,当删除记录时也一样。这样就带来以下有缺点:
操作其中对象的速度快 只需要改变连接,新的节点可以在内存中的任何地方
不能随即访问 虽然存在get()方法,但是这个方法是通过遍历接点来定位的所以速度慢。
以下是初步学习LinkedList源码总结而成,仅供参考。
public class JLinkedList {
//定义链表头
Node<E> first;
//定义链表尾
Node<E> last;
//定义链表长度,即size
int size;
//定义默认的添加方法
public boolean add(E e) {
linkLast(e);
return true;
}
//定义链表插入方法,和JDK自带方法一致,为插入不是替换
public void add(int index, E e){
checkIndexMul(index);
if (index == size) //长度为链表长度,即为在末尾追加,和add(E e)方法一致
linkLast(e);
else //在链表长度以内,则插入链表
linkBefore(e,node(index));
}
//插入链表具体方法,node为当前节点原始的值
private void linkBefore(E e, Node<E> node) {
Node<E> beforeNode = node.prev; //取出当前节点的前一节点
Node<E> newNode = new Node<E>(beforeNode,e,node); //用前一节点和当前原始节点构造出新的节点值
node.prev = newNode; //将节点前后链接起来,双向链表,顺向逆向都要串联起来
if (beforeNode != null)
beforeNode.next = newNode;
else
first = newNode;
size++;
}
//检查节点,抛出异常
private void checkIndexMul(int index) {
if (!checkIndexMulException(index)){
throw new IndexOutOfBoundsException("size out of bounds exception. size="+size+",index="+index);
}
}
private boolean checkIndexMulException(int index) {
return index >= 0 && index <= size;
}
//在链表结尾进行插入
void linkLast(E e){
Node<E> l = last; //若链表为空,则last为空,否则则为链表尾节点
Node<E> newNode = new Node<E>(l,e,null); //构造出新添加节点
last = newNode; //重置链表尾节点
if (size == 0)
first = newNode;
else
l.next = newNode;
size++;
}
public E get(int index){
checkIndex(index);
return node(index).element;
}
private Node<E> node(int index) {
if (index < (size >> 1)){ //size>>1, 即为获取当前链表一半的长度,进行二分法查询,增加效率
Node<E> indexNode = first;
for (int i=0; i<index; i++)
indexNode = indexNode.next; //链表查询耗时之处,需要从链表头到尾依次查询
return indexNode;
}else {
Node<E> indexNode = last;
for (int i=size-1; i>index; i--)
indexNode = indexNode.prev;
return indexNode;
}
}
private void checkIndex(int index) {
if (!checkIndexException(index)){
throw new IndexOutOfBoundsException("size out of bounds exception. size="+size+",index="+index);
}
}
private boolean checkIndexException(int index) {
return index >= 0 && index < size;
}
public int size() {
return size;
}
private static class Node<E>{ //链表节点
Node<E> prev; //存放上一节点的内存地址
Node<E> next; //存放下一节点的内存地址
E element; //存放元素内容
public Node(Node<E> prev, E element, Node<E> next) {
this.prev = prev;
this.next = next;
this.element = element;
}
}
}