LinkedList源码分析

LinkedList源码分析

一、准备工作

package com.liu.List;

import sun.util.resources.cldr.it.CalendarData_it_IT;

import java.util.Iterator;
import java.util.LinkedList;

public class LinkedList_ {
    public static void main(String[] args) {
        LinkedList<Object> linkedList = new LinkedList<>();
        linkedList.add(1);
        linkedList.add(2);
        linkedList.add(3);

        Iterator<Object> iterator = linkedList.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println("linkedList=>"+linkedList);
        }

        linkedList.remove();
        System.out.println(linkedList);
    }
}

二、源码分析

第一次添加

进入构造函数

/**
 * Constructs an empty list.
 */
public LinkedList() {
}

跳出构造函数

进行装箱操作

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

进入add方法

public boolean add(E e) {
    linkLast(e);
    return true;
}

进入linkLast(双向链表的尾插法)

/**
 * Links e as last element.
 */
void linkLast(E e) {
    //新建一个节点l指向last
    final Node<E> l = last;
    //新建节点newNode,    new  Node<>(pre,item,next)   所以l为newNode的pre结点,item为
    //newNode的数据域,null为newNode的next节点
    final Node<E> newNode = new Node<>(l, e, null);
    //last指向newNode
    last = newNode;
    
    if (l == null)//若链表为空
        first = newNode;//则将新节点指定为first
    else
        l.next = newNode;//将newNode插入到最后一个节点后
    size++;
    modCount++;
}

流程图

在这里插入图片描述

第二次添加

进入add

public boolean add(E e) {
    linkLast(e);
    return true;
}

进入linkLast(e);

/**
 * Links e as last element.
 */
void 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++;
}

流程图

在这里插入图片描述

跳出add方法

remove方法

进入remove

public E remove() {
    return removeFirst();
}

进入removeFirst()

public E removeFirst() {
    final Node<E> f = first;       //新建一个指向first的结点f
    if (f == null)//判断链表是否为空
        throw new NoSuchElementException();
    return unlinkFirst(f);
}

进入unlinkFirst()

/**
 * Unlinks non-null first node f.
 */
private E unlinkFirst(Node<E> f) {
    // assert f == first && f != null;
    final E element = f.item;       //记录first节点的元素值
    final Node<E> next = f.next;    //新建一个next结点,记录first节点的下一结点
    f.item = null;                  //清空first结点
    f.next = null; // help GC       //断掉first指向下一节点的指针
    first = next;                   //重新将first结点指向下一节点
    if (next == null)//若next为null,表示链表为空
        last = null; //则last也指向null
    else
        next.prev = null;//将next节点的pre指针断掉
    size--;
    modCount++;
    return element;
}

三、总结(重点)

LinkedList底层是双向链表

remove()方法默认移除第一个元素,同样也有移除末尾元素的方法,所以可以当作双端队列来使用

LinkedList插入方式为尾插法

LinkedList适用于大量数据的增删操作,因为可以动态添加删除节点,而无需考虑扩容问题

ArrayList适用于大量数据的修改和查询操作(可以直接通过下标访问),但增删效率较低,因为底层为数组,需要考虑扩容问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值