LinkList源码分析
- 前言
- 一、接口实现
- 二、成员变量
- 三、list类型方法
- boolean add(E e)
- void addFirst(E e)
- void addLast(E e)
- void add(int index, E element)
- boolean addAll(Collection<? extends E> c)与boolean addAll(int index, Collection<? extends E> c)
- E remove()
- E remove(int index)
- boolean remove(Object o)
- E removeFirst()
- E removeLast()
- boolean removeFirstOccurrence(Object o)
- boolean removeLastOccurrence(Object o)
- 四、queue属性方法
前言
底层数据结构为双向链表,查询慢,增删快;
线程不安全,但效率高;
没有下标,但可以用算法模拟数组下标操作。
提示:以下是本篇文章正文内容,下面案例可供参考
一、接口实现
LinkList同时实现了list与queqe接口
二、成员变量
Size:当前数据量
First:第一个节点
Last:最后一个节点
Node内部类
Item:当前节点数据
Next:下一个节点
Prev:上一个节点
三、list类型方法
boolean add(E e)
实际调用liklast方法
- 获取当前链表的最后一个节点
- 创建当前数据节点
- 将链表最后一个节点指向当前节点
- 判定链表最后一个节点是否为空,如果为空则代表第一次新增,则他也是第一个节点;如果不为空,则将链表最后一个节点的next指向当前节点。
void addFirst(E e)
在头部插入
- 获取链表的第一个节点f
- 构建新节点,它的下一个节点指向f
- 设置链表的第一个节点为newNode
如果f为空则代表是链表的第一次插入,则链表的last也为newNode,如果不为空则设置f的上一个节点为newNode
void addLast(E e)
在尾部插入
- 获取链表的最后一个节点l
- 构建新节点,它的上一个节点指向l
- 设置链表的最后一个节点为newNode
如果l为空则代表是链表的第一次插入,则链表的first也为newNode,如果不为空则设置l的下一个节点为newNode
void add(int index, E element)
指定位置插入节点
- 检查插入下标大于当前数据量则抛出IndexOutOfBoundsException索引越界异常
- 判定当前下标是否与size一致,如果一致是在链表最后插入,与add(E element)方法一致;如果不一致则进入linkBefore方法
- 该方法为获取当前下坐标节点,如果当前下坐标小于size的一半则采用头遍历获取数据;大于size一半则采用尾遍历获取数据
在上面拿到链表指定下坐标节点(succ)后进行节点的重组 - 获取succ的上一个节点pred
- 创建新的节点(newNode),也就是插入数据的节点,他的上一个节点指向pred,下一个节点指向succ
- 设置succ的上一个节点为newNode
- 如果succ的上一个节点为null,则succ为头节点,链表的都节点将会变更为newNode;如果不为null,则设置pred的下一个节点为newNode;完成链表的节点的重组
boolean addAll(Collection<? extends E> c)与boolean addAll(int index, Collection<? extends E> c)
两个公共接口实际使用的都是同一个方法
- 指定下标检查如果大于size则抛出IndexOutOfBoundsException索引越界异常
- 获取集合的数组,如果为空数据则直接返回false
- 提前声明上一个节点pred与下一个节点succ,如果index为size则代表集合在尾部插入,succ为null,pred为最后一个节点;如果index与size不相等则代表在链表中间或头插入,succ为index节点,pred为index节点的上一个节点;
- 遍历集合,构建当前数据节点,他的上一节点指向pred,如果pred为null则代表是在头部插入数据,则设置first为当前节点,如果不为null则设置pred的下一个节点为当前节点
- 对pred重新赋值为当前节点,为下一次循环做准备
- 完成循环之后处理最后一个节点,如果succ为空则代表是尾插入集合,设置last为集合最后一个节点即pred,如果不为null则代表是在链表中间插入,则设置循环最后一个节点即pred的next指向succ,succ的上一个节点指向pred
E remove()
删除第一个节点
- 获取第一个节点,如果为空则抛出NoSuchElementException无数据异常
- 传入unlinkfirst方法
- 获取第一个节点的item
- 获取第一个节点的下一个节点next
- 第一个节点的item、next置空,利于垃圾回收
- 设置first为next如果next为空则代表链表原本就只有一个节点,则设置链表last为空;如果不为空则设置next的上一个节点为空
E remove(int index)
删除指定下标节点
- 检查下标大于等于size则会抛出IndexOutOfBoundsException索引越界异常
- 获取index节点数据传入unlink方法
- 获取当前节点的item
- 获取当前节点下一个节点next
- 获取当前节点的上一个节点prev
- 如果prev为空则代表当前节点为头结点,设置first为next,如果不为空则将prev的下一个节点设置为next
- 如果next为空则代表当前节点为尾节点,设置last为prev,如果不为空则将next的上一个节点设置为prev
- 设置当前节点item为空,利于回收
boolean remove(Object o)
删除第一次出现的指定数据
判断当前数据是否为空,如为空则头遍历链表,获取第一个没有数据的节点,并执行删除unlink方法(E remove(int index) 有讲到);如果不为空则头遍历链表,通过equals方法判断第一个与目标数据相同的节点,并执行unlink方法(E remove(int index) 有讲到)
E removeFirst()
删除第一个节点
实际执行方法为unlinkFirst方法(E remove() 有讲到)
E removeLast()
删除最后一个节点
- 获取最后一个节点,如果为空则会抛出NoSuchElementException无数据异常
- 执行unlinkLast方法
- 获取当前节点数据item
- 获取当前节点的上一个节点prev
- 当前节点的item、prev置空,利于回收
- 设置链表最后一个节点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()
队列方法,检索并删除此列表的头(第一个元素)。
- 获取链表的第一个数据
- 如果不为空将会删除第一个节点,实际执行方法为unlinkFirst方法(E remove() 方法中有讲到)
E pollFirst()
队列方法,检索并删除此列表的第一个元素,如果此列表为空,则返回null。
- 获取链表的第一个数据
- 如果不为空将会删除第一个节点,实际执行方法为unlinkFirst方法(E remove() 方法中有讲到)
E pollLast()
队列方法,检索并删除此列表的最后一个元素,如果此列表为空,则返回null。
- 获取链表的最后一个数据
- 如果不为空将会删除最后一个节点,实际执行方法为unlinkLast方法(E removeLast() 方法中有讲到)
E pop()
队列方法,从此列表表示的堆栈中弹出一个元素。换句话说,删除并返回此列表的第一个元素。
- 队列方法,删除第一个节点
- 实际执行方法为removeFirst(与E removeFirst() 一致)
void push(E e)
队列方法,将元素压入此列表表示的堆栈。换句话说,将元素插入此列表的前面。
实际执行方法为addFirst(与 void addFirst(E e) 一致)