linkedList小记
linkedList继承关系图
field属性
//集合大小
transient int size = 0;
//上一个节点
transient Node<E> first;
//下一个节点
transient Node<E> last;
Node
private 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;
}
}
构造函数
public LinkedList() {
}
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
常用方法
私有方法,用于内部使用,参考jdk原码,不完全一样
/**
* 将该元素放在第一个位置
* @param e
*/
private void linkFirst(E e) {
final Node<E> f = first;
// 前驱为空,值为e,后继为f
final Node<E> newNode = new Node<>(null, e, f);
first = newNode;// first指向newNode
// 此时的f有可能为null
if (f == null)// 若f为空,则表明列表中还没有元素
last = newNode;// last也应该指向newNode
else
f.prev = newNode;// 否则,前first的前驱指向newNode
size++;
modCount++;
}
/**
* 最后面添加节点
* Links e as last element.
*/
private void linkLast(E e) {
final Node<E> f = last;
//前驱为之前的last
final Node<E> newNode = new Node<>(f, e, null);
last = newNode;// first指向newNode
// 此时的f有可能为null
if (f == null)// 若f为空,则表明列表中还没有元素
first = newNode;// last也应该指向newNode
else
f.next = newNode;// 否则,前first的前驱指向newNode
size++;
modCount++;
}
//删除第一个节点
private E unlinkFirst(Node<E> f) {
final E element = first.item;
Node next = f.next;
first = next;
//帮助gc回收
f.item=null;
f.next=null;
if(next==null){
last=null;
}else{
next.prev=null;
}
size--;
modCount++;
return element;
}
//删除最后一个节点
private E unlinkLast(Node<E> l) {
E e = l.item;
Node<E> pre = l.prev;
last = pre;
l.prev=null;
l.item=null;
if(pre==null){
first=null;
}else{
pre.next=null;
}
size--;
modCount++;
return null;
}
/**
* 在某个元素之前添加元素
* @param e 新增的元素
* @param succ 之前的元素
*/
private void linkBefore(E e, Node<E> succ) {
Node<E> prev = succ.prev;
Node<E> newNode = new Node<>(prev,e,succ);
succ.prev=newNode;
if(prev==null){
first=newNode;
}else{
prev.next=newNode;
}
size++;
modCount++;
}
/**
* 删除某个节点
*
*/
private E unlink(Node<E> e) {
E item = e.item;
Node<E> prev = e.prev;
Node<E> next = e.next;
if(prev==null){
first=next;
}else{
prev.next=next;
e.prev=null;
}
if(next==null){
last=prev;
}else{
next.prev=prev;
e.next=null;
}
e.item=null;
size--;modCount++;
return item;
}
/**
* 根据下标查找节点
*
*/
private 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;
}
}
常用方法实现
/**
* 大小
*/
@Override
public int size() {
return size;
}
/**
* 头部新增元素,调用上面的linkFirst
*/
@Override
public void addFirst(E e) {
linkFirst(e);
}
/**
* 尾部新增元素,调用上面的linkLast
*/
@Override
public void addLast(E e) {
linkLast(e);
}
//删除头
@Override
public E removeFirst() {
Node<E> f = first;
if(f==null) throw new NoSuchElementException();
return unlinkFirst(f);
}
//删除尾
@Override
public E removeLast() {
Node<E> l = first;
if(l==null) throw new NoSuchElementException();
return unlinkLast(l);
}
//根据下标获取元素
@Override
public E get(int index) {
ArrayUtils.checkIndex(index,size);
Node<E> x = node(index);
return (E)x.item;
}
//获取头
@Override
public E getFirst() {
if(first==null)throw new NoSuchElementException();
return first.item;
}
//获取尾
@Override
public E getLast() {
if(last==null)throw new NoSuchElementException();
return last.item;
}
//删除尾
@Override
public E remove() {
Node<E> node = last;
if(node==null)throw new NoSuchElementException();
unlinkLast(last);
return node.item;
}
//根据下标删除
@Override
public E remove(int index) {
ArrayUtils.checkIndex(index,size);
Node<E> node = node(index);
unlink(node);
return node.item;
}
/**
* 迭代器实现
*/
@Override
public Iterator<E> iterator() {
return new Itr();
}
迭代器
private class Itr implements Iterator<E>{
int cursor = 0; // 返回下一个元素的下标
int lastRet = -1; // 最后一次操作元素的下标
// prevent creating a synthetic constructor
private Itr() {}
@Override
public boolean hasNext() {
return cursor!=size;
}
@Override
public E next() {
ArrayUtils.checkIndex(cursor,size+1);
lastRet = cursor;
cursor++;
Node<E> node = node(lastRet);
return node.item;
}
@Override
public void remove() {
ArrayUtils.checkIndex(cursor,size+1);
if (lastRet < 0)
throw new IllegalStateException();
unlink(node(lastRet));
cursor=lastRet;
lastRet=-1;
}
}
linkedList学习笔记