linkedlist源码解读
来源:互联网 发布:阿里云域名控制台 编辑:程序博客网 时间:2024/06/03 17:50
说明:本源码linkedlist是采用eclipse的插件Decomplier反编译器查看的jdk1.8的愿码
package java.util;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.AbstractSequentialList;
import java.util.Collection;
import java.util.Deque;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.Spliterator;import java.util.LinkedList.1;
import java.util.LinkedList.DescendingIterator;
import java.util.LinkedList.LLSpliterator;
import java.util.LinkedList.ListItr;
import java.util.LinkedList.Node;
/// 双向队列 支持clone复制 支持序列化
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, Serializable {
//大小不支持序列化
transient int size;
//首节点
transient Node<E> first;
///尾接点
transient Node<E> last;
//序列化ID
private static final long serialVersionUID = 876323262645176354L;
//默认构造函数
public LinkedList() {
this.size = 0;
}
///通过集合初始化
public LinkedList(Collection<? extends E> arg0) {
this();
this.addAll(arg0);
}
//
private void linkFirst(E arg0) {
Node arg1 = this.first; ///首节点 当前对象的首节点赋予第一个元素
Node arg2 = new Node((Node) null, arg0, arg1);
///创建一个节点 包含三个参数 null 形参 第一节点,元素分装成节点
this.first = arg2;
///把新节点指向首节点
if (arg1 == null) {
this.last = arg2;//如果当前首节点为空,新节点指向尾节点,(什么时候首节点为null?即是size=0的时候)
} else {
arg1.prev = arg2;//prev前一个节点,data当前数据 next下一节点 如果当前首节点不为null,则前一节点的前为当前节点(换句话说就是把前的节点的前指向新节点)
}
++this.size; //长度加一
++this.modCount;//改变加一
}
/////如上linkFurst的逻辑
///如果当前的尾接点为null,和首节点链起来,不为空就把以前的下一个节点指向新接点
void linkLast(E arg0) {
Node arg1 = this.last;
Node arg2 = new Node(arg1, arg0, (Node) null);
this.last = arg2;
if (arg1 == null) {
this.first = arg2;
} else {
arg1.next = arg2;
}
++this.size;
++this.modCount;
}
///指定节点前加入节点 元素 节点
void linkBefore(E arg0, Node<E> arg1) {
Node arg2 = arg1.prev;//arg2:指定节点的前一节点
Node arg3 = new Node(arg2, arg0, arg1);///加入的元素分装成节点
arg1.prev = arg3; ///把新节点变成指定节点的前一节点
if (arg2 == null) {
this.first = arg3;///如果指定元素为前节点null,则新节点为首节点
} else {
arg2.next = arg3;//如果指定元素前一节点元素不为空,把前一节点的指向回来的重新指向新节点
}
++this.size;//打小加一
++this.modCount;//改变加一
}
///删除首节点,返回首节点的值
private E unlinkFirst(Node<E> arg0) {
Object arg1 = arg0.item;///获取传入节点的值
Node arg2 = arg0.next; ///获取传入节点的后一个节点
arg0.item = null; ///释放传入节点,
arg0.next = null;//和下个节点
this.first = arg2; ///把后面节点给首节点
if (arg2 == null) { ///如果下个节点为空(什么时候会出现这种情况?)
this.last = null; //说明最后个节点为null
} else {
arg2.prev = null; ///把后一个点的前面指向为null(因为arg2已经变成首节点了)
}
--this.size; //大小减一
++this.modCount;//改变的次数加一
return arg1; //返回传入节点的值(首节点de值)
}
////如上删除最后个节点,把最后节点内容和向前的方向赋为null,并且当前面的节点存在时候,把前面节点指向最后的赋为null,,返回尾节点的值
private E unlinkLast(Node<E> arg0) {
Object arg1 = arg0.item;
Node arg2 = arg0.prev;
arg0.item = null;
arg0.prev = null;
this.last = arg2;
if (arg2 == null) {
this.first = null;
} else {
arg2.next = null;
}
--this.size;
++this.modCount;
return arg1;
}
//删除指定节点,返回删除节点的值
E unlink(Node<E> arg0) {
Object arg1 = arg0.item;//当前节点内容
Node arg2 = arg0.next; //下个节点
Node arg3 = arg0.prev;//前个节点
if (arg3 == null) { ///如果前个节点为null
this.first = arg2; //说明:当前节点删掉的情况下,首节点是下个节点
} else {
arg3.next = arg2; //前个节点不为null,把前个节点的后指向指向后节点,越过删除的节点
arg0.prev = null;///删除的节点前指向为null
}
if (arg2 == null) { ///后节点为null
this.last = arg3; //在删除节点的前提下,前节点变成尾节点了
} else {
arg2.prev = arg3;//后节点不为空,后节点的前指向为前节点,越过删除节点
arg0.next = null;//删除节点的后指向为null
}
arg0.item = null;//删除节点
--this.size;//大小减一
++this.modCount;//改变次数加一
return arg1;返回删除的节点的值
}
///获取首个位的值,不能为空
public E getFirst() {
Node arg0 = this.first;
if (arg0 == null) {
throw new NoSuchElementException();
} else {
return arg0.item;
}
}
///获取尾位的值
public E getLast() {
Node arg0 = this.last;
if (arg0 == null) {
throw new NoSuchElementException();
} else {
return arg0.item;
}
}
//移除首位,返回首位值。。首位后指向和后位前指向为null。。。。。
public E removeFirst() {
Node arg0 = this.first;
if (arg0 == null) {
throw new NoSuchElementException();
} else {
return this.unlinkFirst(arg0);
}
}
//移除末尾
public E removeLast() {
Node arg0 = this.last;
if (arg0 == null) {
throw new NoSuchElementException();
} else {
return this.unlinkLast(arg0);
}
}
//添加首位
public void addFirst(E arg0) {
this.linkFirst(arg0);
}
//添加尾位
public void addLast(E arg0) {
this.linkLast(arg0);
}
//是否包含元素
public boolean contains(Object arg0) {
return this.indexOf(arg0) != -1;
}
//包含大小
public int size() {
return this.size;
}
//添加尾位,返回true
public boolean add(E arg0) {
this.linkLast(arg0);
return true;
}
//删除指定元素,当为null,删除首节点,不为null,删除指定,没有为false
public boolean remove(Object arg0) {
Node arg1;
if (arg0 == null) {///为null,删除首节点,返回true
for (arg1 = this.first; arg1 != null; arg1 = arg1.next) {
if (arg1.item == null) {
this.unlink(arg1);
return true;
}
}
} else { //不为null删除指定元素
for (arg1 = this.first; arg1 != null; arg1 = arg1.next) {
if (arg0.equals(arg1.item)) {
this.unlink(arg1);
return true;
}
}
}
return false;
}
///添加集合 从末尾开始加入集合
public boolean addAll(Collection<? extends E> arg0) {
return this.addAll(this.size, arg0);
}
///
public boolean addAll(int arg0, Collection<? extends E> arg1) {
this.checkPositionIndex(arg0);///保证输入的数0到size之间(包含0和size)
Object[] arg2 = arg1.toArray();//数组转化成集合
int arg3 = arg2.length;//集合的长度
if (arg3 == 0) {
return false; //输入为集合是null时候
} else {
Node arg4;//定义两个节点
Node arg5;
if (arg0 == this.size) {//如果输入值的大小为链的大小,即从链的尾位下一个开始的时候(包含下一位)
arg5 = null;
arg4 = this.last;//把尾节点赋予节点4
} else { //如果输入值比链小,说明输入的argo在下标所在的范围0-(size-1)之间
arg5 = this.node(arg0);//查出下标所在的节点
arg4 = arg5.prev;//将接点5前指向节点4
}
Object[] arg6 = arg2;///将填入的数组填入变量6
int arg7 = arg2.length;//将要填入的长度
for (int arg8 = 0; arg8 < arg7; ++arg8) { //开始循环加入连中
Object arg9 = arg6[arg8];
Node arg11 = new Node(arg4, arg9, (Node) null);//创建新节点,指向上面新建的前节点
if (arg4 == null) { //如果前节点为null
this.first = arg11; //新节点为首节点
} else {
arg4.next = arg11; //前节点不为null,前节点的后节点指向新建的节点 (把输入下标的节点覆盖了)
}
arg4 = arg11;//新接点成为前节点,为下次循环做准备
}///从整个循环可以看出,这里所为的添加是从输入的下标的前节点接着下来的
if (arg5 == null) {///对应上面输入值为链大小值
this.last = arg4;//上面循环更新后的最后后位赋予尾位
} else {
arg4.next = arg5;//如果不为null在把前面循环断开的接在最后跟新的尾位上
arg5.prev = arg4;
}
this.size += arg3; //添加的节点大小加上集合的大小
++this.modCount;//修改的次数加一
return true;
}
}
///清空
public void clear() {
Node arg1;
for (Node arg0 = this.first; arg0 != null; arg0 = arg1) {
arg1 = arg0.next;
arg0.item = null;
arg0.next = null;
arg0.prev = null;
}
this.first = this.last = null;
this.size = 0;
++this.modCount;
}
////获取指定下标的值
public E get(int arg0) {
this.checkElementIndex(arg0);///格式检查,从0到size (含0不含size)
return this.node(arg0).item;
}
///设置指定节点的值,返回旧值
public E set(int arg0, E arg1) {
this.checkElementIndex(arg0);//格式检查,从0到size(不含size)
Node arg2 = this.node(arg0);//选出当前节点
Object arg3 = arg2.item;//当前节点的值
arg2.item = arg1;//把值赋予给当前节点的值
return arg3;//返回的以前节点的旧值
}
//把后元素节点添加在下标节点之前
public void add(int arg0, E arg1) {
this.checkPositionIndex(arg0);
if (arg0 == this.size) {///如果输入的值为长度的值,
this.linkLast(arg1);//添加到尾元素
} else {
this.linkBefore(arg1, this.node(arg0));
}
}
//移除指定下标的节点
public E remove(int arg0) {
this.checkElementIndex(arg0);
return this.unlink(this.node(arg0));
}
private boolean isElementIndex(int arg0) {
return arg0 >= 0 && arg0 < this.size;
}
private boolean isPositionIndex(int arg0) {
return arg0 >= 0 && arg0 <= this.size;
}
//超出边界详情
private String outOfBoundsMsg(int arg0) {
return "Index: " + arg0 + ", Size: " + this.size;
}
private void checkElementIndex(int arg0) {
if (!this.isElementIndex(arg0)) {
throw new IndexOutOfBoundsException(this.outOfBoundsMsg(arg0));
}
}
private void checkPositionIndex(int arg0) {
if (!this.isPositionIndex(arg0)) {
throw new IndexOutOfBoundsException(this.outOfBoundsMsg(arg0));
}
}
////查找下标所在的节点,方法把size分半,前半从首位找过去,后半从尾位找过去:可以得出个结论,处于中间的查找最慢!!!
Node<E> node(int arg0) {///0和2位值,1为节点
Node arg1;
int arg2;
if (arg0 < this.size >> 1) {//当前输入的值在size的前半部分
arg1 = this.first;
for (arg2 = 0; arg2 < arg0; ++arg2) {
arg1 = arg1.next;
}
return arg1;///返回下标所在的节点
} else {///当前输入的值在size的后半部分
arg1 = this.last;
for (arg2 = this.size - 1; arg2 > arg0; --arg2) {
arg1 = arg1.prev;
}
return arg1;//返回所在的节点
}
}
////找到元素所在的下标
public int indexOf(Object arg0) {
int arg1 = 0;
Node arg2;
if (arg0 == null) {//查找的元素为null
for (arg2 = this.first; arg2 != null; arg2 = arg2.next) {
if (arg2.item == null) {
return arg1; ////如果查找的元素为null 就返回最近为null的次数的循环的(下标),只能查一个null
}
++arg1;
}
} else { //查找的元素不为null
for (arg2 = this.first; arg2 != null; arg2 = arg2.next) {
if (arg0.equals(arg2.item)) {
return arg1; //不为null就返回所在的下标
}
++arg1;
}
}
return -1;//1.查为null时候,不存在位null的.2.查元素不存在
}
///查找元素最后出现位置,原理如上
public int lastIndexOf(Object arg0) {
int arg1 = this.size;
Node arg2;
if (arg0 == null) {
for (arg2 = this.last; arg2 != null; arg2 = arg2.prev) {
--arg1;
if (arg2.item == null) {
return arg1;
}
}
} else {
for (arg2 = this.last; arg2 != null; arg2 = arg2.prev) {
--arg1;
if (arg0.equals(arg2.item)) {
return arg1;
}
}
}
return -1;
}
//返回第一个元素
public E peek() {
Node arg0 = this.first;
return arg0 == null ? null : arg0.item;
}
public E element() {
return this.getFirst();
}
///返回第一个元素值,并删除
public E poll() {
Node arg0 = this.first;
return arg0 == null ? null : this.unlinkFirst(arg0);
}
//删除首元素,并返回值
public E remove() {
return this.removeFirst();
}
///添加到末尾
public boolean offer(E arg0) {
return this.add(arg0);
}
//添加到第一个
public boolean offerFirst(E arg0) {
this.addFirst(arg0);
return true;
}
//添加到末尾
public boolean offerLast(E arg0) {
this.addLast(arg0);
return true;
}
//返回首元素的值
public E peekFirst() {
Node arg0 = this.first;
return arg0 == null ? null : arg0.item;
}
//返回尾元素的值
public E peekLast() {
Node arg0 = this.last;
return arg0 == null ? null : arg0.item;
}
//删除首元素并返回值
public E pollFirst() {
Node arg0 = this.first;
return arg0 == null ? null : this.unlinkFirst(arg0);
}
//删除尾源素,并返回值
public E pollLast() {
Node arg0 = this.last;
return arg0 == null ? null : this.unlinkLast(arg0);
}
//加入首元素
public void push(E arg0) {
this.addFirst(arg0);
}
//删除首元素并返回值
public E pop() {
return this.removeFirst();
}
//移除指定下标位置
public boolean removeFirstOccurrence(Object arg0) {
return this.remove(arg0);
}
//从后向前开始删除指定元素
public boolean removeLastOccurrence(Object arg0) {
Node arg1;
if (arg0 == null) {//如果输入的值为null
for (arg1 = this.last; arg1 != null; arg1 = arg1.prev) {
if (arg1.item == null) {
this.unlink(arg1);//如果出现节点数据为null,删除并返回true
return true;
}
}
} else {//如果不为null
for (arg1 = this.last; arg1 != null; arg1 = arg1.prev) {
if (arg0.equals(arg1.item)) {
this.unlink(arg1);//删除指定元素节点
return true;
}
}
}
return false;
}
//迭代
public ListIterator<E> listIterator(int arg0) {
this.checkPositionIndex(arg0);
return new ListItr(this, arg0);
}
public Iterator<E> descendingIterator() {
return new DescendingIterator(this, (1)null);
}
private LinkedList<E> superClone() {
try {
return (LinkedList) super.clone();
} catch (CloneNotSupportedException arg1) {
throw new InternalError(arg1);
}
}
///linkedlist复制
public Object clone() {
LinkedList arg0 = this.superClone();
arg0.first = arg0.last = null;
arg0.size = 0;
arg0.modCount = 0;
for (Node arg1 = this.first; arg1 != null; arg1 = arg1.next) {
arg0.add(arg1.item);
}
return arg0;
}
///把linkedlist集合翻译成数组 返回
public Object[] toArray() {
Object[] arg0 = new Object[this.size];
int arg1 = 0;
for (Node arg2 = this.first; arg2 != null; arg2 = arg2.next) {
arg0[arg1++] = arg2.item;
}
return arg0;
}
//额,貌似bug??????
public <T> T[] toArray(T[] arg0) {
if (arg0.length < this.size) {//如果输入的数组大小小于linkedlist的大小,将他重新按类型,大小创建个新的数组
arg0 = (Object[]) ((Object[]) Array.newInstance(arg0.getClass().getComponentType(), this.size));
}
int arg1 = 0;
Object[] arg2 = arg0;
for (Node arg3 = this.first; arg3 != null; arg3 = arg3.next) {
arg2[arg1++] = arg3.item; //集合变成数组
}
if (arg0.length > this.size) {
arg0[this.size] = null;///如果输入的数组大于当前集合 多余的部分为null
}
return arg0;////????
}
///写入(对象)linkedlist
private void writeObject(ObjectOutputStream arg0) throws IOException {
arg0.defaultWriteObject();
arg0.writeInt(this.size);
for (Node arg1 = this.first; arg1 != null; arg1 = arg1.next) {
arg0.writeObject(arg1.item);
}
}
//读出(对象)linkedlist
private void readObject(ObjectInputStream arg0) throws IOException, ClassNotFoundException {
arg0.defaultReadObject();
int arg1 = arg0.readInt();
for (int arg2 = 0; arg2 < arg1; ++arg2) {
this.linkLast(arg0.readObject());
}
}
public Spliterator<E> spliterator() {
return new LLSpliterator(this, -1, 0);
}
}
好了,上面是关于linkedlist的愿码解读,关于arraylist,敬请期待!!!!
- Java--LinkedList源码解读
- java LinkedList源码解读
- LinkedList源码解读
- java LinkedList 源码解读
- LinkedList源码解读
- linkedlist源码解读
- java源码解读之LinkedList------jdk 1.7
- Java之LinkedList源码解读(JDK 1.8)
- jdk1-8-0-73源码解读——LinkedList实现
- LinkedList源码
- LinkedList源码
- LinkedList源码
- LinkedList源码
- 【源码】LinkedList源码剖析
- JDK源码-LinkedList源码
- 源码解读
- LinkedList 源码分析
- LinkedList源码分析
- 控制芯片类型简称
- 平均最短路径长度——网络建模之基本指标
- 筛法加强版
- Linux Shell脚本攻略 学习笔记 --- 第一天
- 科普一下: 电子的速度很慢,比乌龟还慢, 比蚂蚁还慢!
- linkedlist源码解读
- Codeforces Round #442 (Div. 2)(思路题)
- 聊聊SIGCHLD信号的作用
- 51nod 1407 与与与与 dp+容斥
- 菜单
- 状态模式学习和思考
- ubuntu常用软件安装
- Django 和mysql通信得插件windows下安装mysql-python报错的解决办法
- RGB颜色模式