LinkedList 源码解析 JDK1.7
这是第二个java中通用的数据结构
这和之前的 ArrayList 中的很多 接口有相同的…
如果这里没有提及…可以去 https://blog.csdn.net/weixin_46592754/article/details/105866191 看一下
本文…
LinkedList 层次结构
接口
Queue
从注释中摘抄的一段 作者 DougLea
他说… queue 每一种操作都有2个方法 , 一个会抛出异常, 一个会返回具体的值
也就是 加入队列为空 那么 poll 会返回null remove 会抛异常 同理… 看一下这个表格就行…
Throws exception | Returns special value | |
Insert | {@link #add add(e)} | {@link #offer offer(e)} |
Remove | {@link #remove remove()} | {@link #poll poll()} |
Examine | {@link #element element()} | {@link #peek peek()} |
Deque
因为扩展了 queue 所以方法之间 有一些对应关系…
这些都是取自 源码注释的…
Queue Method | Equivalent Deque Method |
{@link java.util.Queue#add add(e)} | {@link #addLast addLast(e)} |
{@link java.util.Queue#offer offer(e)} | {@link #offerLast offerLast(e)} |
{@link java.util.Queue#remove remove()} | {@link #removeFirst removeFirst()} |
{@link java.util.Queue#poll poll()} | {@link #pollFirst pollFirst()} |
{@link java.util.Queue#element element()} | {@link #getFirst getFirst()} |
{@link java.util.Queue#peek peek()} | {@link #peek peekFirst()} |
剩下的方法都是 addFirst 啊 啥的… 感觉不用多说 - - 反正都用过
抽象类
AbstractSequentialList
注释中对于这个类的解释
说 如果 要使用的是顺序访问. 就像linked list 才需要实现这个类… 这个类提供了 顺序访问的 set get方法
和AbstractList做法相反… 如果要提供随机访问 最好实现 AbstractList 而不是这个类
做法确实相反…
AbstractList 的实现 策略 都是 使用迭代器 调用自身的 remove 方法 和 add 方法
而这个类 恰恰相反… 使用自身调用 迭代器的remove方法… 因此 迭代器的方法 都是抽象的
我还发现…虽然linkedList 继承了这个抽象类…但是几乎所有方法都已经覆盖掉了
public abstract class AbstractSequentialList<E> extends AbstractList<E> {
//set get 方法 都不展示了.. 都是调用的 迭代器的方法...
public abstract ListIterator<E> listIterator(int index);
}
类
LinkedList
整体的实现 基本与 ArrayList一致… 没有扩容机制… 因为底层使用的是链表的 存储结构
当然比ArrayList 多实现的. .就是 Queue的部分了… 有栈和队列的一些操作…
使用链表的数据结构存储 带来的好处 就是插入特别的快… 查询会比较慢… 平均 还是需要O(n)的
虽然我发现…查询的时候还是有小小的优化在… 会先判断查询的index 离头节点近 还是尾节点近…
1.7的源码 都是基础的数据结构操作…感觉没有什么特别奇怪的特殊的地方…linkedList 整体偏简单的- -
自己看一遍都是能看懂的 … . … … … … . . … ( 狗头 )
//使用的还是双向链表
private static 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;
}
}
额外补充… 在番源码的时候发现
/**
remove(Object )方法 , 所使用的是 对象的 equals方法.. 不存在hashcode的比较
**/
public boolean remove(Object o) {
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null) {
unlink(x);
return true;
}
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item)) {
unlink(x);
return true;
}
}
}
return false;
}