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

网站建设金手指排名霸屏主机类型wordpress

网站建设金手指排名霸屏,主机类型wordpress,网易企业邮箱设置pop3,福建建设执业资格注册中心网站Java 中的 LinkedList —— 这是一个基于双向链表的集合类,与 ArrayList 的数组结构形成鲜明对比。一、LinkedList 的底层结构1. 底层实现:双向链表LinkedList 是基于 双向链表(Doubly Linked List) 实现的,每个节点包…

Java 中的 LinkedList —— 这是一个基于双向链表的集合类,与 ArrayList 的数组结构形成鲜明对比。


一、LinkedList 的底层结构

1. 底层实现:双向链表

  • LinkedList 是基于 双向链表(Doubly Linked List) 实现的,每个节点包含:
    • 数据(element
    • 前驱节点指针(prev
    • 后继节点指针(next
private static class Node<E> {E item;Node<E> next;Node<E> prev;Node(Node<E> prev, E element, Node<E> next) {this.item = element;this.next = next;this.prev = prev;}
}
  • LinkedList 维护两个头尾指针:
    • first:指向链表的第一个节点
    • last:指向链表的最后一个节点

二、LinkedList 的核心特性

特性说明
有序元素按插入顺序存储
可重复允许重复元素
动态大小插入/删除时自动调整链表长度
线程不安全多线程下需手动同步
允许 null可以存储 null 值
双向链表支持正向和反向遍历

 三、时间复杂度对比(与 ArrayList 对比)

操作LinkedListArrayList
get(index)O(n)O(1) ⚡️
add(E e)O(1)(尾部)均摊 O(1)(偶尔扩容 O(n))
add(index, E e)O(n)(需定位)O(n)(需移动元素)
remove(index)O(n)(需定位)O(n)(需移动元素)
contains(E e)O(n)O(n)
内存占用高(每个节点额外存储 prev/next)低(仅存储元素)

一句话:

  • 随机访问ArrayList 更快
  • 中间插入/删除LinkedList 更快
  • 尾部操作:两者接近(LinkedList 无扩容开销)

四、LinkedList vs ArrayList 的核心区别

对比项LinkedListArrayList
底层结构双向链表动态数组
随机访问O(n)O(1)
插入/删除(中间)O(1)(已知位置)O(n)(需移动元素)
内存占用高(每个节点有 prev/next 指针)低(仅存储元素)
适用场景频繁中间插入/删除频繁随机访问、尾部操作
                                                                线程都不安全
是否支持 RandomAccess支持(但慢)支持(且快)

如果业务中主要是频繁在中间插入或删除,且不常随机访问,LinkedList 更合适;如果是频繁按索引查询或尾部操作ArrayList 性能更好。


五、LinkedList 的常见操作源码解析

1. 添加元素(尾部)

public boolean add(E e) {linkLast(e); // 直接添加到尾部return true;
}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++;
}
  • 时间复杂度:O(1)

2. 插入元素(指定位置)

public void add(int index, E element) {checkPositionIndex(index);if (index == size) {linkLast(element);} else {Node<E> succ = node(index); // 找到指定位置的节点Node<E> pred = succ.prev;Node<E> newNode = new Node<>(pred, element, succ);succ.prev = newNode;if (pred == null) {first = newNode;} else {pred.next = newNode;}size++;modCount++;}
}
  • 时间复杂度:O(n)(需定位节点)

六、LinkedList 的线程安全问题

1. 线程不安全

  • LinkedList 不是线程安全的。多线程环境下,如果多个线程同时修改(如 add/remove),可能导致数据不一致或异常。

2. 如何保证线程安全?

方法说明使用场景
Collections.synchronizedList()包装成同步列表通用
CopyOnWriteArrayList写时复制,读不加锁读多写少
手动加锁使用 synchronized 或 ReentrantLock灵活控制
// 方式1:同步包装
List<String> syncList = Collections.synchronizedList(new LinkedList<>());// 方式2:使用 CopyOnWriteArrayList
List<String> cowList = new CopyOnWriteArrayList<>();

对比

  • synchronizedList:所有操作加锁,性能较低。
  • CopyOnWriteArrayList:写操作复制整个数组,开销大,但读操作无锁,适合“读多写少”场景(如监听器列表)。

七、LinkedList 的 fail-fast 机制

  • LinkedList 的迭代器同样基于 modCount 实现 fail-fast 机制。
  • 原理
    • 迭代器创建时保存 expectedModCount = modCount
    • 每次 next() 前检查 modCount == expectedModCount,不一致则抛出 ConcurrentModificationException
final void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();
}
  • 单线程下,边遍历边修改也会触发异常。
  • 正确删除方式:使用 Iterator.remove(),它会同步更新 expectedModCount

八、LinkedList 的一些理论问题

1. 为什么 LinkedList 的随机访问效率低?

因为 LinkedList 是基于链表实现的,访问第 n 个元素需要从头节点或尾节点遍历到目标位置,时间复杂度为 O(n)

// LinkedList 的 get(index) 实现
public E get(int index) {checkElementIndex(index);return node(index).item;
}Node<E> node(int index) {// 如果 index 在前半部分,从头开始遍历// 否则从尾开始遍历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;}
}

2. LinkedList 和 ArrayList 的适用场景?

场景推荐使用
频繁随机访问ArrayList
频繁中间插入/删除LinkedList
尾部频繁操作ArrayList(无扩容开销)
读多写少CopyOnWriteArrayList

3. LinkedList 的内存占用为什么比 ArrayList 高?

LinkedList 的每个节点除了存储元素外,还需要存储 prevnext 指针,导致内存开销比 ArrayList 大。


4. 如何高效删除 LinkedList 中的所有值为 100 的元素?

推荐方式

// 使用迭代器(避免并发修改异常)
Iterator<Integer> it = list.iterator();
while (it.hasNext()) {if (it.next() == 100) {it.remove(); // ✅ 安全删除}
}// 或使用 removeIf(Java 8+)
list.removeIf(x -> x == 100);

 九、LinkedList 的优缺点总结

优点缺点
插入/删除效率高(O(1),已知位置)随机访问效率低(O(n))
尾部添加无需扩容内存占用高(每个节点有指针)
支持双向遍历(ListIterator不适合频繁随机访问的场景

十、实际应用

  1. 何时选择 LinkedList

    • 需要频繁在头部或中间插入/删除元素(如任务队列、历史记录)。
    • 不需要频繁随机访问元素。
  2. 何时避免 LinkedList

    • 需要频繁按索引访问元素(如日志查询、缓存)。
    • 内存敏感场景(链表节点指针占用额外内存)。

 十一、得到的技巧

题目:如何高效合并两个有序的 LinkedList?

 参考

// 使用双指针合并两个有序链表
public static LinkedList<Integer> mergeTwoSortedLists(LinkedList<Integer> l1, LinkedList<Integer> l2) {LinkedList<Integer> result = new LinkedList<>();Node<Integer> p1 = l1.getFirstNode(), p2 = l2.getFirstNode();while (p1 != null && p2 != null) {if (p1.item <= p2.item) {result.add(p1.item);p1 = p1.next;} else {result.add(p2.item);p2 = p2.next;}}// 添加剩余元素while (p1 != null) {result.add(p1.item);p1 = p1.next;}while (p2 != null) {result.add(p2.item);p2 = p2.next;}return result;
}

解释

  • 时间复杂度:O(m + n)
  • 空间复杂度:O(m + n)

最后总结:LinkedList 核心要点

考点答案
底层结构双向链表
随机访问性能O(n)(需遍历)
插入/删除性能O(1)(已知位置)
内存占用高(每个节点有指针)
与 ArrayList 的区别链表 vs 数组,插入删除 vs 随机访问
线程安全否,需用 synchronizedList 或 CopyOnWriteArrayList
fail-fast 机制与 ArrayList 一致,迭代时修改会抛异常
适用场景频繁中间插入/删除,不适合随机访问
http://www.dtcms.com/a/523529.html

相关文章:

  • uniapp微信小程序简单表格展示
  • 【html】每日打卡页面
  • Server 15 ,VMware ESXi 实战指南:Ubuntu 20.04.6 版本虚拟机静态 IP 配置、分辨率固定及远程访问实践
  • 吴恩达深度学习课程一:神经网络和深度学习 第三周:浅层神经网络(三)
  • Copilot使用体验
  • uniapp video 加载完成后全屏播放
  • 从MongoDB到国产数据库:一场2TB电子证照系统的“平滑着陆”实践
  • 电子商务网站开发与建设试卷wordpress如何删除已安装主题
  • 内蒙古城乡建设网站免费详情页模板网站
  • Android EDLA开发认证说明和开发流程
  • DevExpress WPF中文教程:Data Grid - 如何使用虚拟源?(三)
  • UniApp缓存系统详解
  • 【LLM】用 FastAPI 搭建「OpenAI 兼容」DeepSeek-OCR 服务 + 简洁WebUI
  • 企业内部SRE/DevOps向精通Linux课程培训大纲
  • 《Effective Java》第13条:谨慎的覆盖clone
  • 第一章、React + TypeScript + Webpack项目构建
  • 前端:金丝雀部署(Canary Deployment)/ A、B部署 / 灰度部署
  • Spark微博舆情分析系统 情感分析 爬虫 Hadoop和Hive 贴吧数据 双平台 讲解视频 大数据 Hadoop ✅
  • 宁波公司网站建设价格dw建设手机网站
  • 长沙做网站价格有哪些网站可以做青旅义工
  • 怎么查看网站打开速度企业网站用vps还是虚拟主机
  • Vue3 模板引用——ref
  • XGBoost完整学习指南:从数据清洗到模型调参
  • 【深度学习新浪潮】AI Agent工具流产品:从原理到落地,打造智能协作新范式
  • 页面滚动加载更多
  • 除了provide和inject,Vue3还有哪些用于组件通信的方式?
  • React 表单与事件
  • AI代码开发宝库系列:FAISS向量数据库
  • 前端埋点学习
  • Spring AI与DeepSeek实战:打造企业级知识库+系统API调用