一步一步解析集合框架LinkedList源码(2)

我在阅读源码的过程中很多时候是没有头绪的。所以为了避免大家也遇到这种状况,源码不求全求大,做到“透过实践看源码”,分块分层。

  • 首先创建集合对象,添加数据
    public static void main(String[] args) {
        LinkedList<String> list=new LinkedList<String>();
        list.add("first");
        list.add("second");
    }

源码分析:
相关属性:

    //链表元素数量
    transient int size = 0;

    /**
     * 链表首节点
     */
    transient Node<E> first;

    /**
     * 链表尾节点
     */
    transient Node<E> last;

    /**
     * 构造函数
     */
    public LinkedList() {
    }

以上并没有进行什么初始化操作;

  • 添加数据
    /**
     * 添加数据元素
     */
    public boolean add(E e) {
        linkLast(e);
        return true;
    }
    /**
     * 将元素e添加至链表末尾,
     * 双向的,类似于:first--->A---->B---->...--->last
     *                  <--  <---  <--- ...<--
     */
    void linkLast(E e) {
        //第一次添加数据,因为last并没有实例化,所以l不是指向last的引用,l=null
        final Node<E> l = last;
        //根据添加的元素创建一个节点,将last节点作为prev节点,next节点设置为空,随后设置
        final Node<E> newNode = new Node<>(l, e, null);
        //将新构建的节点作为last节点,保证每次添加都添加至末尾
        last = newNode;
        //第一次添加,将first指向newNode节点(新构建的)
        if (l == null)
            first = newNode;
        else
            l.next = newNode;//以后每次都将最后一个节点的next只想新节点
        size++;//元素数递增
        modCount++;
    }
  • 添加数据还可以使用压入push
    public static void main(String[] args) {
        LinkedList<String> list=new LinkedList<String>();
        list.add("first");
        list.add("second");
        list.push("zero");
    }

源码分析:

    /**
     * 压入
     * 在首节点处增加数据
     */
    public void push(E e) {
        addFirst(e);
    }
    /**
     * 在首节点添加数据
     */
    public void addFirst(E e) {
        linkFirst(e);
    }
    /**
     * 作为首节点链接入集合
     */
    private void linkFirst(E e) {
        final Node<E> f = first;
        //构造新节点,指定next节点是first
        final Node<E> newNode = new Node<>(null, e, f);
        first = newNode;
        //第一次添加数据,f==null;first和last均指向新节点
        if (f == null)
            last = newNode;
        else
            f.prev = newNode;//成功构建双向节点,加入链表
        size++;
        modCount++;
    }
  • 获取链表元素值
    public static void main(String[] args) {
        LinkedList<String> list=new LinkedList<String>();
        list.add("first");
        list.add("second");
        list.push("zero");
        System.out.println(list.getFirst());
        System.out.println(list.getLast());
    }

运行结果:

zero
second

源码分析:

    /**
     * 返回链表第一个元素值
     */
    public E getFirst() {
        final Node<E> f = first;
        //未添加数据,f==null,抛出异常
        if (f == null)
            throw new NoSuchElementException();
        return f.item;//节点值
    }

    /**
     * 返回最后一个节点值
     */
    public E getLast() {
        final Node<E> l = last;
        if (l == null)
            throw new NoSuchElementException();
        return l.item;//节点值
    }
  • 删除数据
    public static void main(String[] args) {
        LinkedList<String> list=new LinkedList<String>();
        list.add("first");
        list.add("second");
        list.push("zero");
        list.remove("zero");
        System.out.println(list.getFirst());
        System.out.println(list.getLast());
    }

运行结果:

first
second

源码分析:

    /**
     *根据值进行删除
     */
    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;
    }
    /**
     * 删除节点x
     */
    E unlink(Node<E> x) {
        // assert x != null;
        final E element = x.item;
        final Node<E> next = x.next;
        final Node<E> prev = x.prev;
        //如果删除的是第一个节点,prev=null
        if (prev == null) {
            first = next;
        } else {
            //重新指定链接
            prev.next = next;
            x.prev = null;//解除链接
        }
       //如果删除的是最后一个节点
        if (next == null) {
            last = prev;
        } else {
            //重新指定链接
            next.prev = prev;
            x.next = null;//解除链接
        }

        x.item = null;//清空
        size--;
        modCount++;
        return element;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值