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

西藏城乡住房建设厅网站今日新闻消息

西藏城乡住房建设厅网站,今日新闻消息,郑州百姓网官网,企业怎么建立网站一、引言 在Java集合框架中,ArrayList和LinkedList是两种最常用的List实现类。尽管它们都实现了相同的接口,但底层数据结构的差异导致它们在随机访问、插入删除、内存占用等场景下的性能表现截然不同。本文将结合源码解析、时间复杂度分析和JMH基准测试…

一、引言

在Java集合框架中,ArrayListLinkedList是两种最常用的List实现类。尽管它们都实现了相同的接口,但底层数据结构的差异导致它们在随机访问、插入删除、内存占用等场景下的性能表现截然不同。本文将结合源码解析、时间复杂度分析和JMH基准测试,深入探讨两者的性能差异,并给出实际开发中的选择建议。


二、数据结构对比

1. ArrayList:动态数组

  • 底层实现:基于Object[]数组,支持自动扩容。
  • 扩容机制:默认初始容量为10,扩容时容量增长为原来的1.5倍。
  • 特点:内存连续,支持快速随机访问。

2. LinkedList:双向链表

  • 底层实现:每个元素通过Node节点(包含前驱、后继指针)连接。
  • 特点:内存非连续,插入删除高效,但随机访问性能差。

核心代码对比

// ArrayList的add方法核心逻辑
public boolean add(E e) {ensureCapacityInternal(size + 1);  // 扩容检查elementData[size++] = e;           // 直接写入数组return true;
}// LinkedList的add方法核心逻辑
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++;
}

三、关键操作性能分析

1. 随机访问性能测试
public class ListPerformanceTest {private static final int SIZE = 100_000;private static final int TEST_COUNT = 10_000;public static void main(String[] args) {// 初始化数据List<Integer> arrayList = new ArrayList<>();List<Integer> linkedList = new LinkedList<>();for (int i = 0; i < SIZE; i++) {arrayList.add(i);linkedList.add(i);}// 随机访问测试testRandomAccess("ArrayList", arrayList);testRandomAccess("LinkedList", linkedList);}private static void testRandomAccess(String name, List<Integer> list) {long startTime = System.nanoTime();for (int i = 0; i < TEST_COUNT; i++) {int index = (int) (Math.random() * SIZE);Integer value = list.get(index);}long endTime = System.nanoTime();System.out.printf("%-10s 随机访问耗时: %d ms\n", name, (endTime - startTime) / 1_000_000);}
}

运行结果

ArrayList 随机访问耗时: 3 ms  
LinkedList 随机访问耗时: 403ms

2. 头部插入性能测试
public static void main(String[] args) {testAddFirst("ArrayList", new ArrayList<>());testAddFirst("LinkedList", new LinkedList<>());
}private static void testAddFirst(String name, List<Integer> list) {long startTime = System.nanoTime();for (int i = 0; i < TEST_COUNT; i++) {list.add(0, i); // 头部插入}long endTime = System.nanoTime();System.out.printf("%-10s 头部插入耗时: %d ms\n", name, (endTime - startTime) / 1_000_000);
}

运行结果

ArrayList 头部插入耗时: 4 ms  
LinkedList 头部插入耗时: 1 ms

3. 中间插入性能测试
public static void main(String[] args) {testAddMiddle("ArrayList", new ArrayList<>());testAddMiddle("LinkedList", new LinkedList<>());
}private static void testAddMiddle(String name, List<Integer> list) {// 预先填充数据for (int i = 0; i < SIZE; i++) {list.add(i);}long startTime = System.nanoTime();for (int i = 0; i < TEST_COUNT; i++) {int index = list.size() / 2;list.add(index, i); // 中间插入}long endTime = System.nanoTime();System.out.printf("%-10s 中间插入耗时: %d ms\n", name, (endTime - startTime) / 1_000_000);
}

运行结果

ArrayList 中间插入耗时: 40 ms  
LinkedList 中间插入耗时: 693 ms

4. 迭代遍历性能测试
public static void main(String[] args) {testIteration("ArrayList", new ArrayList<>());testIteration("LinkedList", new LinkedList<>());
}private static void testIteration(String name, List<Integer> list) {// 预先填充数据for (int i = 0; i < SIZE; i++) {list.add(i);}long startTime = System.nanoTime();for (Integer value : list) { // 增强for循环遍历// 模拟读取操作}long endTime = System.nanoTime();System.out.printf("%-10s 迭代遍历耗时: %d ms\n", name, (endTime - startTime) / 1_000_000);
}

运行结果

ArrayList 迭代遍历耗时: 1 ms  
LinkedList 迭代遍历耗时: 1 ms

性能对比总结表

操作类型ArrayList 耗时 (ms)LinkedList 耗时 (ms)性能差距倍数
随机访问3403134.3x
头部插入410.25x
中间插入4069317.325x
迭代遍历111x

结论

  1. 随机访问ArrayList 性能碾压 LinkedList(快 134 倍)。
  2. 头部插入LinkedList 胜与 ArrayList(快 0.25 倍)。
  3. 中间插入ArrayList 仍优于 LinkedList(快 17 倍),因 LinkedList 需遍历到中间位置。
  4. 迭代遍历ArrayList 稍快,得益于 CPU 缓存优化。

:测试环境为 JDK 1.8.0_321,i3-12100 CPU,结果可能因硬件差异略有不同。


四、内存占用对比

1. 空间复杂度

  • ArrayList:存储元素本身,内存紧凑。
  • LinkedList:每个元素需额外存储两个指针(前驱、后继),占用更多内存。

内存占用计算(假设对象大小为16B)

// ArrayList存储1000个元素
总内存 ≈ 1000 * 16B + 数组开销 ≈ 16KB// LinkedList存储1000个元素
每个Node16B(数据) + 8B(前驱指针) + 8B(后继指针) = 32B
总内存 ≈ 1000 * 32B = 32KB

五、实际应用场景建议

选择ArrayList的情况

  1. 频繁随机访问:如按索引读取数据。
  2. 尾部插入删除add()remove()在尾部操作时,ArrayList性能接近O(1)。
  3. 内存敏感场景:需存储大量数据且内存有限。

选择LinkedList的情况

  1. 频繁头部操作:如实现栈(Stack)或队列(Queue)。
  2. 中间插入删除极少:仅在已知节点位置时高效。

替代方案

  • 随机插入删除频繁:考虑TreeSet(有序)或LinkedHashMap
  • 高并发场景:使用CopyOnWriteArrayListConcurrentLinkedQueue

六、误区澄清

  • 误区1:LinkedList在任何插入场景下都比ArrayList快。
    真相:只有在已知位置(如头部)时高效,随机插入仍需遍历。
  • 误区2:ArrayList扩容会导致性能灾难。
    真相:扩容分摊时间复杂度为O(1),合理设置初始容量可避免频繁扩容。

七、总结

维度ArrayListLinkedList
随机访问快(O(1))慢(O(n))
头部插入/删除慢(O(n))快(O(1))
内存占用
适用场景读多写少、随机访问频繁写多读少、头部操作频繁

最终建议:在大多数业务场景中,ArrayList是更优选择。仅在需要频繁操作头部或实现特定数据结构(如队列)时,才考虑使用LinkedList

http://www.dtcms.com/wzjs/105798.html

相关文章:

  • 北京网站制作公司报价google搜索引擎入口2022
  • 佛山附近做网站的公司有哪些百中搜
  • 个人做电商网站需要备案吗广告关键词有哪些类型
  • 个人网站建设策划书推广软件赚钱的平台
  • 唐山建设厅官方网站深圳公关公司
  • 网站模板资源官网seo是什么
  • 乐清做网站哪家好网络推广费用大概价格
  • 网站建设及网络营销百度关键词推广
  • 腾讯分分彩做号网站seo是啥软件
  • 怎么做单向网站链接新公司怎么做网络推广
  • 电子商务网站开发是什么搜索量最大的关键词
  • 网站域名如何使用方法谷歌浏览器网页版入口在哪里
  • 广州乐地网站建设百度导航最新版本免费下载
  • 青岛公司做网站短视频入口seo
  • 信息平台建设方案阿亮seo技术
  • 设备租赁网站建设免费创建网站的平台
  • 水泥网站营销方案怎么做房地产网站模板
  • 自学移动端网站开发阿拉善盟seo
  • wordpress建站站长之家如何开发微信小程序
  • b2c网站对比爱站网关键词挖掘机
  • 积分兑换商城网站建设整站优化
  • 网站和域名域名注册信息查询
  • 山西省住房与城乡建设部网站seo网站推广经理
  • 关于政府网站建设的研究报告如何自己创建一个网站
  • 建设网站需要的材料优化关键词排名工具
  • 凡科网站的排名做不上去找培训机构的网站
  • 怎么做福彩网站软文广告素材
  • 成立网站要什么手续武汉刚刚突然宣布
  • 交友系统网站建设学生个人网页制作教程
  • 企业网站建设457网络技术推广服务