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

深圳苍松大厦 网站建设厦门网站建设报价

深圳苍松大厦 网站建设,厦门网站建设报价,dedecms wap网站模板下载,免费网站加速器一、引言 在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/543833.html

相关文章:

  • 网站建设痛点广东网页制作推广
  • 艺梵科技 网站建设wordpress通知邮件美化
  • 网站关键字多少个怎么做网站链接的快捷方式
  • 潍坊路通工程建设有限公司网站php网站开发案例pdf
  • 哈尔滨门户网站建设管理咨询公司有哪些
  • 公司做网站设计要注意微信微网站开发百度云
  • 上海网站制作设计公司天津百度推广中心
  • 网站联盟是什么嘉兴网站定制
  • wordpress软件网站模板下载网页传奇手游
  • 专做腰带的网站wordpress页面上下级
  • 做网站品免费个人网站+上传
  • 和各大网站做视频的工作总结湖南 seo
  • 用照片做视频的模板下载网站好关键字挖掘
  • 帮人做微信是哪个网站WordPress分类目录图标
  • 我的网站域名是什么咸阳网站网站建设
  • 江门网站建设推广平台WordPress启用主题无反应
  • 二级域名做网站注意徐州网站建设市场分析
  • 网站设计定做建设培训网站办安全员c证
  • cn域名有名的网站网页设计与制作的模板
  • 网站建设 时间安排做外贸网站可以收付款吗
  • 网站建设渠道员建立网站内容需要做的事
  • 黄冈商城网站建设哪家好济南科技市场做网站
  • 厦门市房地产建设局网站品牌建设还需持续力
  • 君临天下游戏网站开发者珠海做网站的公司介绍
  • 专门做网站的合肥做公司网站一般多少钱
  • 上海公上海公司网站建设微信开发者工具怎么用
  • 进口外贸网站有哪些wordpress 列表函数
  • 萝岗区营销型网站建设网页模板免费版
  • 承德网站制作公司优选网十科技新人做网站盈利
  • 网站开发后怎么转安卓app哪个公司可以专门做网站