java - LinkList源码分析


前言

底层数据结构为双向链表,查询慢,增删快;
线程不安全,但效率高;
没有下标,但可以用算法模拟数组下标操作。


提示:以下是本篇文章正文内容,下面案例可供参考

一、接口实现

LinkList同时实现了list与queqe接口
在这里插入图片描述

二、成员变量

Size:当前数据量
First:第一个节点
Last:最后一个节点
在这里插入图片描述

Node内部类

Item:当前节点数据
Next:下一个节点
Prev:上一个节点
在这里插入图片描述

三、list类型方法

boolean add(E e)

实际调用liklast方法
在这里插入图片描述

  1. 获取当前链表的最后一个节点
  2. 创建当前数据节点
  3. 将链表最后一个节点指向当前节点
  4. 判定链表最后一个节点是否为空,如果为空则代表第一次新增,则他也是第一个节点;如果不为空,则将链表最后一个节点的next指向当前节点。
    在这里插入图片描述

void addFirst(E e)

在头部插入

  1. 获取链表的第一个节点f
  2. 构建新节点,它的下一个节点指向f
  3. 设置链表的第一个节点为newNode
    如果f为空则代表是链表的第一次插入,则链表的last也为newNode,如果不为空则设置f的上一个节点为newNode
    在这里插入图片描述
    在这里插入图片描述

void addLast(E e)

在尾部插入

  1. 获取链表的最后一个节点l
  2. 构建新节点,它的上一个节点指向l
  3. 设置链表的最后一个节点为newNode
    如果l为空则代表是链表的第一次插入,则链表的first也为newNode,如果不为空则设置l的下一个节点为newNode
    在这里插入图片描述
    在这里插入图片描述

void add(int index, E element)

指定位置插入节点

  1. 检查插入下标大于当前数据量则抛出IndexOutOfBoundsException索引越界异常
  2. 判定当前下标是否与size一致,如果一致是在链表最后插入,与add(E element)方法一致;如果不一致则进入linkBefore方法
    在这里插入图片描述
  3. 该方法为获取当前下坐标节点,如果当前下坐标小于size的一半则采用头遍历获取数据;大于size一半则采用尾遍历获取数据
    在这里插入图片描述
    在上面拿到链表指定下坐标节点(succ)后进行节点的重组
  4. 获取succ的上一个节点pred
  5. 创建新的节点(newNode),也就是插入数据的节点,他的上一个节点指向pred,下一个节点指向succ
  6. 设置succ的上一个节点为newNode
  7. 如果succ的上一个节点为null,则succ为头节点,链表的都节点将会变更为newNode;如果不为null,则设置pred的下一个节点为newNode;完成链表的节点的重组
    在这里插入图片描述

boolean addAll(Collection<? extends E> c)与boolean addAll(int index, Collection<? extends E> c)

两个公共接口实际使用的都是同一个方法
在这里插入图片描述

  1. 指定下标检查如果大于size则抛出IndexOutOfBoundsException索引越界异常
  2. 获取集合的数组,如果为空数据则直接返回false
  3. 提前声明上一个节点pred与下一个节点succ,如果index为size则代表集合在尾部插入,succ为null,pred为最后一个节点;如果index与size不相等则代表在链表中间或头插入,succ为index节点,pred为index节点的上一个节点;
  4. 遍历集合,构建当前数据节点,他的上一节点指向pred,如果pred为null则代表是在头部插入数据,则设置first为当前节点,如果不为null则设置pred的下一个节点为当前节点
  5. 对pred重新赋值为当前节点,为下一次循环做准备
  6. 完成循环之后处理最后一个节点,如果succ为空则代表是尾插入集合,设置last为集合最后一个节点即pred,如果不为null则代表是在链表中间插入,则设置循环最后一个节点即pred的next指向succ,succ的上一个节点指向pred
    在这里插入图片描述
    在这里插入图片描述

E remove()

删除第一个节点

  1. 获取第一个节点,如果为空则抛出NoSuchElementException无数据异常
  2. 传入unlinkfirst方法
    在这里插入图片描述
    在这里插入图片描述
  3. 获取第一个节点的item
  4. 获取第一个节点的下一个节点next
  5. 第一个节点的item、next置空,利于垃圾回收
  6. 设置first为next如果next为空则代表链表原本就只有一个节点,则设置链表last为空;如果不为空则设置next的上一个节点为空
    7.

E remove(int index)

删除指定下标节点

  1. 检查下标大于等于size则会抛出IndexOutOfBoundsException索引越界异常
  2. 获取index节点数据传入unlink方法
    在这里插入图片描述
  3. 获取当前节点的item
  4. 获取当前节点下一个节点next
  5. 获取当前节点的上一个节点prev
  6. 如果prev为空则代表当前节点为头结点,设置first为next,如果不为空则将prev的下一个节点设置为next
  7. 如果next为空则代表当前节点为尾节点,设置last为prev,如果不为空则将next的上一个节点设置为prev
  8. 设置当前节点item为空,利于回收
    在这里插入图片描述

boolean remove(Object o)

删除第一次出现的指定数据
判断当前数据是否为空,如为空则头遍历链表,获取第一个没有数据的节点,并执行删除unlink方法(E remove(int index) 有讲到);如果不为空则头遍历链表,通过equals方法判断第一个与目标数据相同的节点,并执行unlink方法(E remove(int index) 有讲到)
在这里插入图片描述

E removeFirst()

删除第一个节点
实际执行方法为unlinkFirst方法(E remove() 有讲到)
在这里插入图片描述

E removeLast()

删除最后一个节点

  1. 获取最后一个节点,如果为空则会抛出NoSuchElementException无数据异常
  2. 执行unlinkLast方法
    在这里插入图片描述
  3. 获取当前节点数据item
  4. 获取当前节点的上一个节点prev
  5. 当前节点的item、prev置空,利于回收
  6. 设置链表最后一个节点last为prev
    如果prev为空,则代表删除的节点也同样为头节点,则设置头结点为空;如果不为空则设置prev的下一个节点为null
    在这里插入图片描述

boolean removeFirstOccurrence(Object o)

从头遍历链表删除第一个出现的指定元素
实际执行方法为remove方法(boolean remove(Object o) 有讲到)
在这里插入图片描述

boolean removeLastOccurrence(Object o)

从尾遍历链表删除第一个出现的指定元素
与boolean remove(Object o) 方法中的remove相似,区别之处在于一个为头遍历,一个为尾遍历
在这里插入图片描述

四、queue属性方法

boolean offer(E e)

队列方法,将指定的元素添加为此列表的尾部
实际执行add方法(与boolean add(E e) 一致)
在这里插入图片描述

boolean offerFirst(E e)

队列方法,将指定的元素插入此列表的前面
实际执行的方法为addFirst(与 void addFirst(E e) 一致)
在这里插入图片描述

boolean offerLast(E e)

队列方法,将指定的元素插入此列表的末尾。
实际执行的方法为addLast(与 void addLast(E e) 一致)
在这里插入图片描述

E peek()

队列方法,检索但不删除此列表的第一个元素,如果此列表为空,则返回 null。
在这里插入图片描述

E peekFirst()

队列方法,检索但不删除此列表的第一个元素,如果此列表为空,则返回 null。
在这里插入图片描述

E peekLast()

队列方法,检索但不删除此列表的最后一个元素,如果此列表为空,则返回 null。
在这里插入图片描述

E poll()

队列方法,检索并删除此列表的头(第一个元素)。

  1. 获取链表的第一个数据
  2. 如果不为空将会删除第一个节点,实际执行方法为unlinkFirst方法(E remove() 方法中有讲到)
    在这里插入图片描述

E pollFirst()

队列方法,检索并删除此列表的第一个元素,如果此列表为空,则返回null。

  1. 获取链表的第一个数据
  2. 如果不为空将会删除第一个节点,实际执行方法为unlinkFirst方法(E remove() 方法中有讲到)
    在这里插入图片描述

E pollLast()

队列方法,检索并删除此列表的最后一个元素,如果此列表为空,则返回null。

  1. 获取链表的最后一个数据
  2. 如果不为空将会删除最后一个节点,实际执行方法为unlinkLast方法(E removeLast() 方法中有讲到)
    在这里插入图片描述

E pop()

队列方法,从此列表表示的堆栈中弹出一个元素。换句话说,删除并返回此列表的第一个元素。

  1. 队列方法,删除第一个节点
  2. 实际执行方法为removeFirst(与E removeFirst() 一致)
    在这里插入图片描述

void push(E e)

队列方法,将元素压入此列表表示的堆栈。换句话说,将元素插入此列表的前面。
实际执行方法为addFirst(与 void addFirst(E e) 一致)
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值