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,敬请期待!!!!

原创粉丝点击