当前位置: 首页 > news >正文

LinkedList集合源码解析

LinkedList 集合

LinkedList 是一个基于双向链表实现的集合类

LinkedList 实现了以下接口:

  • List : 表明它是一个列表,支持添加、删除、查找等操作,并且可以通过下标进行访问。
  • Deque :继承自 Queue 接口,具有双端队列的特性,支持从两端插入和删除元素,方便实现栈和队列等数据结构。
  • Cloneable :表明它具有拷贝能力,可以进行深拷贝或浅拷贝操作。
  • Serializable : 表明它可以进行序列化操作,也就是可以将对象转换为字节流进行持久化存储或网络传输。

public class LinkedList extends AbstractSequentialList<E>implements List<E>, Deque<E>, Cloneable, java.io.Serializable  {// 列表大小transient int size = 0;/*** Pointer to first node.* Invariant: (first == null && last == null) ||* (first.prev == null && first.item != null)* 列表的头节点*/transient Node<E> first;/*** Pointer to last node.* Invariant: (first == null && last == null) ||* (last.next == null && last.item != null)* 列表的尾节点*/transient Node<E> last;// 根据索引获取节点Node<E> node(int index) {// assert isElementIndex(index);// 索引index < size/2 则从前往后遍历if (index < (size >> 1)) {// 获取到头节点Node<E> x = first;for (int i = 0; i < index; i++)x = x.next;return x;} else {// 获取尾节点Node<E> x = last;for (int i = size - 1; i > index; i--)x = x.prev;return x;}}private static class Node<E> {E item; // 当前节点Node的值Node<E> next; // 当前节点的下一个节点NodeNode<E> prev; // 当前节点的上一个节点NodeNode(Node<E> prev, E element, Node<E> next) {this.item = element;this.next = next;this.prev = prev;}}/*** 获取列表长度*/public int size() {return size;}// 初始化LinkedListpublic LinkedList(Collection<? extends E> c) {this();addAll(c);}/*** 在列表头部 增加新的节点*/public void addFirst(E e) {linkFirst(e);}/*** Links e as first element.* 在列表的头节点插入新的元素*/private void linkFirst(E e) {// f = 头节点final Node<E> f = first;// 创建一个新节点, e的前节点为null,下个节点为ffinal Node<E> newNode = new Node<>(null, e, f);// 将头节点设置为新节点first = newNode;// f 标记的头节点为空,则证明当前列表是空的if (f == null)// 列表为空 尾节点last=newNodelast = newNode;else// 否则,原头节点 prev 指向新节点f.prev = newNode;// 长度 + 1size++;// 变化值 + 1modCount++;}/*** 在列表尾部 增加元素*/public void addLast(E e) {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;elsel.next = newNode;size++;modCount++;}/*** Inserts element e before non-null Node succ.* 在指定的节点前插入新的元素* e 新元素* succ 插入到目标* 将 e 元素 插入到 succ 节点之前*/void linkBefore(E e, Node<E> succ) {// assert succ != null;// succ 节点的 前节点final Node<E> pred = succ.prev;// 新建一个节点e 前节点(succ的前节点), 后节点(succ节点)final Node<E> newNode = new Node<>(pred, e, succ);// succ 的前节点 成为 新节点esucc.prev = newNode;// succ.prev为空,则说明succ节点为头节点if (pred == null)// 将头结点改为新节点efirst = newNode;else// 若非头节点,则 succ的前节点 现在 指向 新节点epred.next = newNode;size++;modCount++;}// 删除头节点public E removeFirst() {final Node<E> f = first;if (f == null)throw new NoSuchElementException();return unlinkFirst(f);}/*** 删除头节点*/private E unlinkFirst(Node<E> f) {// assert f == first && f != null;// 头节点的值final E element = f.item;// 头节点的下个节点final Node<E> next = f.next;f.item = null;f.next = null; // help GC// 新的头结点为 原头节点的nextfirst = next;// next为空 则 列表只有一个元素,删除后则为空if (next == null)// 尾节点为空last = null;else// 将原头结点的下个节点prev变为null,next.prev = null;size--;modCount++;return element;}/*** 删除尾节点*/public E removeLast() {final Node<E> l = last;if (l == null)throw new NoSuchElementException();return unlinkLast(l);}/*** Unlinks non-null last node l.* 删除尾节点*/private E unlinkLast(Node<E> l) {// assert l == last && l != null;final E element = l.item;final Node<E> prev = l.prev;l.item = null;l.prev = null; // help GClast = prev;if (prev == null)first = null;elseprev.next = null;size--;modCount++;return element;}// 删除节点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 则 x为头节点if (prev == null) {first = next;} else {// 将x的上个节点的指针,指向x下个节点prev.next = next;// 将x的前指针变为null 便于GC回收x.prev = null;}// next==null 则 x为尾结点if (next == null) {// 新尾结点= x节点的上一个节点last = prev;} else {// 将x的下个节点的前指针指向,x的上个指针next.prev = prev;// 将x的下个指针设置为null 便于GC回收x.next = null;}// x的值设置为null  便于GC回收x.item = null;size--;modCount++;return element;}// 获取头节点值public E getFirst() {// f=获取头结点final Node<E> f = first;if (f == null)throw new NoSuchElementException();// 头结点的值=f.itemreturn f.item;}// 获取为节点值public E getLast() {// 获取尾节点final Node<E> l = last;if (l == null)throw new NoSuchElementException();// 尾节点值return l.item;}// 判断列表是否存在指定元素opublic boolean contains(Object o) {return indexOf(o) != -1;}// 根据元素查找索引, 没有则为-1public int indexOf(Object o) {int index = 0;if (o == null) {for (Node<E> x = first; x != null; x = x.next) {// 判断元素值是否为nullif (x.item == null)return index;index++;}} else {for (Node<E> x = first; x != null; x = x.next) {// 判断元素的值是否为 oif (o.equals(x.item))return index;index++;}}return -1;}// 清空列表public void clear() {// 从头节点开始遍历for (Node<E> x = first; x != null; ) {// 获取下个节点信息Node<E> next = x.next;// 全部设置为nullx.item = null;x.next = null;x.prev = null;// 将下个节点赋值给xx = next;}// 头结点  尾结点 均设置为nullfirst = last = null;// 列表长度设置为 0size = 0;modCount++;}// 判断 index 索引是否越界private void checkPositionIndex(int index) {// 判断 index 索引是否越界if (!isPositionIndex(index))// 越界后打印说明throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}// 判断 index 索引是否越界private boolean isPositionIndex(int index) {return index >= 0 && index <= size;}// 越界后打印说明private String outOfBoundsMsg(int index) {return "Index: "+index+", Size: "+size;}// 迭代器private class ListItr implements ListIterator<E> {// 上一次调用 next() 或 previous() 方法的节点private Node<E> lastReturned;private Node<E> next; // 下个节点private int nextIndex; // 下一个节点的索引// 判断链表是否被其他线程修改过private int expectedModCount = modCount;ListItr(int index) {// assert isPositionIndex(index);// index==size 则表示next是尾节点next = (index == size) ? null : node(index);nextIndex = index;}// 判断是否尾尾结点public boolean hasNext() {return nextIndex < size;}// 获取下一个节点public E next() {// 判断列表是否发生了修改 (modCount 与 记录的expectedModCount是否一致)checkForComodification();if (!hasNext())throw new NoSuchElementException();// 当前节点lastReturned = next;// 下个节点next = next.next;// 下个节点的索引nextIndex++;// 当前节点的值valuereturn lastReturned.item;}// 判断下个节点是否越界public boolean hasPrevious() {return nextIndex > 0;}public E previous() {// 检查列表是否发生修改checkForComodification();// 判断下个节点的索引是否 > 0if (!hasPrevious())throw new NoSuchElementException();// 若当前节点的下个节点为空 则设置为尾结点 lastReturned = next = (next == null) ? last : next.prev;nextIndex--;return lastReturned.item;}public int nextIndex() {return nextIndex;}public int previousIndex() {return nextIndex - 1;}public void remove() {checkForComodification();if (lastReturned == null)throw new IllegalStateException();Node<E> lastNext = lastReturned.next;unlink(lastReturned);if (next == lastReturned)next = lastNext;elsenextIndex--;lastReturned = null;expectedModCount++;}public void set(E e) {if (lastReturned == null)throw new IllegalStateException();checkForComodification();lastReturned.item = e;}public void add(E e) {checkForComodification();lastReturned = null;if (next == null)linkLast(e);elselinkBefore(e, next);nextIndex++;expectedModCount++;}final void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();}}
}
http://www.dtcms.com/a/282125.html

相关文章:

  • 超级天才如何批量制造?天才成长引擎模型:超级天才 = (学习速度泛化力 × 创造力 × 专注力) × 驱动力
  • python基础②-数据结构
  • AlpineLinux的用户管理
  • conda activate 时报错: CondaError: Run ‘conda init‘ before ‘conda activate‘
  • XC7A75T‑2FGG484I Xilinx Artix‑7 FPGA AMD
  • go项目实战
  • 深入解析Linux进程地址空间与虚拟内存管理
  • 虚拟内存管理--请求分页管理方式
  • 15.dispatcherRunner启动
  • 图机器学习(10)——监督学习中的图神经网络
  • LLM大语言模型不适合统计算数,可以让大模型根据数据自己建表、插入数据、编写查询sql统计
  • ether.js的calldata
  • 探索阿里云DMS:解锁高效数据管理新姿势
  • 【WRFDA数据教程第一期】LITTLE_R 格式详细介绍
  • 常用 Benchmark 总结-GPT 4.1、GPT 4.5、DeepSeek模型
  • 【游戏引擎之路】登神长阶(十七):Humanoid动画——长风破浪会有时,直挂云帆济沧海
  • 联网工人安全解决方案:技术赋能下的安全新范式
  • Django REST Framework 入门指南:从 0 到 1 实现 RESTful API
  • 【LLM】OpenRouter调用Anthropic Claude上下文缓存处理
  • cudaOccupancyMaxActiveBlocksPerMultiprocessor配置内核的线程块大小
  • Linux运维新手的修炼手扎之第18天
  • 二刷 黑马点评 分布式锁-redission
  • 【芯片设计中的WDT IP:守护系统安全的电子警犬】
  • HDFS基本操作训练(创建、上传、下载、删除)
  • CSS面试题及详细答案140道之(21-40)
  • 智租换电与中国电信达成战略合作!共筑数字能源新基建
  • LeetCode|Day15|125. 验证回文串|Python刷题笔记
  • GaussDB 预写日志回收参数设置
  • Uniapp中双弹窗为什么无法显示?
  • Java虚拟机——JVM