签名

可以看到,LinkedList 继承了AbstractSequentialList
实现了Cloneable,和序列化接口。
类和接口
AbstractSequentialList——骨架实现(skeletal implementation)类
很多都参照了effective java ,向大佬致敬!!!
优点:把接口和抽象类的优点结合起来。就关了所有与接口实现相关的工作,方便了其他接口的实现
public abstract class AbstractList extends AbstractCollection implements List {
这里的Collection 实现的是包装模式,包装了collection接口
Cloneable
简介:这是一个标记接口,表明这个类重写(Override)了Object.clone()方法,复制这个类是合法的。
Serializable
简介:这个也是一个标记接口,在以前的分析里分析过。
Deque
简介:一个支持两端插入删除的线性集合。deque是double end queue 的简称——即双向队列。。。
成员变量
transient int size = 0;
transient Node first;
transient Node last;
这三个变量很显然,就是分别指向了前,后,size表示这个LinkedList的容量。
Q:size 什么时候不会扩展LinkedList的容量,反而会抛出异常?
transient:
ransient是java语言的关键字,变量修饰符,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。当一个对象被序列化的时候,transient型变量的值不包括在序列化的表示中,然而非transient型的变量是被包括进去的。——引自bing网典
源码剖析
1.构造器
public LinkedList() {
}
public More ...LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
2.方法
add系列
public void More ...addLast(E e) {
linkLast(e);
}
public void More ...addFirst(E e) {
linkFirst(e);
}
public boolean More ...addAll(Collection<? extends E> c) {
return addAll(size, c);
}
public boolean More ...add(E e) {
linkLast(e);
return true;
}
这几个类封装了算法,应该是策略模式。
实际上不是,人家策略算法是指:出行=坐飞机/坐火车/坐自行。。。都封装到一起。这个应该是装饰模式。
public boolean addAll(int index, Collection<? extends E> c) {
checkPositionIndex(index);
//查询是否超出边界。如果超出了,就抛出异常——所以,collection类也是有边界的——问题2:LinkedList是如何扩展它的边界的?为什么在这里不选择扩展边界,而选择抛出异常?
Object[] a = c.toArray();
int numNew = a.length;
if (numNew == 0)
return false;
//检查新添加的collection类是否为空
Node<E> pred, succ;
if (index == size) {
succ = null;
pred = last;
} else {
succ = node(index);
pred = succ.prev;
}//插入
for (Object o : a) {
@SuppressWarnings("unchecked") E e = (E) o;
//@SuppressWarnings——消除注释注解,
问题3:为什么这里会选择用这个?都有什么情况会用这个?
Node<E> newNode = new Node<>(pred, e, null);
if (pred == null)
first = newNode;
else
pred.next = newNode;
pred = newNode;
}
if (succ == null) {
last = pred;
} else {
pred.next = succ;
succ.prev = pred;
}
size += numNew;
modCount++;
return true;
}
link系列——创建链表
void More ...linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
clear()
这个类并不难懂,主要是有意思的是这个注解:
还有 modecount :这里引用一篇文章:
感觉自己的文章深度就不够。日了狗!
有意思的是,AbstractList中的clear(),是调用了一个removeRange来实现的。
先谈一谈LinkedList中的clear();
就算这里有一个可达的Iterator 对node节点的域置为null后,gc也会进行垃圾回收。
启发:不用的对象置为null,可以gc
q:为什么AbstractList会将clear转发给removeRandom?
学长任务:为什么List在使用迭代器迭代的时候,remove某个元素 会抛出异常
既然是List,那么先从AbstractList看起:
public E More ...remove(int index) {
throw new UnsupportedOperationException();
}
额,这个实现总是抛出这个异常——不支持操作- -!;
我们往上看,
抛出异常的原因——f==null
什么时候会造成f==null呢?
我们查看一下Iterator的构造方法:
http://blog.csdn.net/qh_java/article/details/50154405 我去,编不下去了,这篇文章高大上!
3.内部类
Node——节点类
private static class More ...Node<E> {
E item;
Node<E> next;
Node<E> prev;
More ...Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
每个节点都有前驱和后继。
ListItr 类
private class More ...ListItr implements ListIterator<E>
相对于Iterator,增加了与前驱和后继相关的操作,更贴近LinkedList,支持前后操作
DescendingIterator类
单纯实现了Iterator接口。采用了策略模式,封装了ListItr的算法
感觉不叫策略模式啊,这到底算不算个设计模式?
问题4:既然ListItr功能多,为什么还会出现DescendingIterator?