基准测试了 ArrayList 和 LinkedList ,发现我们一直用 ArrayList 也是没什么问题的
ArrayList 应该是 Java 中最常用的集合类型了,以至于我们说到集合就会自然而然的想到 ArrayList。很多同学都没有用过除了 ArrayList 之外的其他集合,甚至于都已经忘了除了 ArrayList 之外的其他集合,例如 LinkedList、Vector 等。
那么我们平时只用 ArrayList 是不是正确呢,我既然知道了 LinkedList、Vector ,是不是也要用一下它呢,那么什么情况下用呢。
Vector 是线程安全的集合类型,所以仅在多线程编程的时候才考虑是否用它,凡是为了多线程设计,必然在性能上有所损失, Vector 只是在每个方法上简单的加上 synchronized 关键字,所以性能损失是肯定的。
那么现在就来比较一下 ArrayList 和 LinkedList,都说插入、删除操作多的话用 LinkedList,插入操作多的话用 ArrayList,产生这种说法的大致依据如下。
ArrayList
内部是用 Object 数组作为存储结构,数组是内存中连续的内存空间,并且继承了 RandomAccess接口,所以可以实现元素的快速访问。但如果不是在末尾插入元素的话,需要拷贝插入位置之后的元素。
LinkedList
内部自己实现的 Node 链表,每个节点都指明了上一节点和下一节点, 所以不要求内存连续,并且插入数据只需要修改上一节点和下一节点的指针即可。但是访问元素需要遍历查找,所以查询元素较慢。
真的是这样吗?下面我做了一系列的测试,来看一下真实的情况。
插入数据
分别从头部、尾部和随机位置插入数据,初始的列表长度分别为 10、1w、10w 来测试几种插入数据的性能,以平均耗时为依据。得到的结果如下:

头部插入数据,ArrayList 耗时明显大于 LinkedList ,得出结论头部插入数据 LinkedList 性能优于 ArrayList,因为在头部位置插入数据时,ArrayList 要拷贝插入位置之后的数据,往后移动一个位置。

尾部插入数据,ArrayList 耗时小于 LinkedList,得出结论:尾部插入数据,ArrayList 性能优于 LinkedList。

随机位置是用 Random 产生的,上限是当前列表长度。可见随机位置插入数据,ArrayList 耗时小于 LinkedList ,得出结论:多次随机位置插入数据,平均性能 ArrayList 优于 LinkedList,注意,这里说的是多次随机插入求的平均值。
插入数据得出以下结论
| 插入位置 | 初始列表长度10 | 初始列表长度1w | 初始列表长度10w |
|---|---|---|---|
| 头部 | LinkedList 优于 ArrayList | LinkedList 优于 ArrayList | LinkedList 优于 ArrayList |
| 尾部 | ArrayList 优于 LinkedList | ArrayList 优于 LinkedList | ArrayList 优于 LinkedList |
| 多次随机位置 | ArrayList 优于 LinkedList | ArrayList 优于 LinkedList | ArrayList 优于 LinkedList |
获取数据
分别从头部、尾部和随机位置获取数据,初始的列表长度分别为1000、10w、100w、1000w 来测试几种获取数据的性能,以吞吐量为判断依据,吞吐量单位是 每毫秒内操作数。得到的结果如下:

头部获取数据,ArrayList 吞吐量大于 LinkedList,得出结论头部获取数据,ArrayList 性能优于 LinkedList

尾部获取数据,ArrayList 吞吐量大于 LinkedList,得出结论尾部获取数据,ArrayList 性能优于 LinkedList

多次随机位置获取数据,ArrayList 吞吐量大于 LinkedList,得出结论多次随机位置获取数据,ArrayList 性能优于 LinkedList
综上,获取数据操作的结论如下
| 获取位置 | 列表长度1000 | 列表长度10w | 列表长度100w | 列表长度1000w |
|---|---|---|---|---|
| 头部 | ArrayList 优于 LinkedList | ArrayList 优于 LinkedList | ArrayList 优于 LinkedList | ArrayList 优于 LinkedList |
| 尾部 | ArrayList 优于 LinkedList | ArrayList 优于 LinkedList | ArrayList 优于 LinkedList | ArrayList 优于 LinkedList |
| 多次随机位置 | ArrayList 优于 LinkedList | ArrayList 优于 LinkedList | ArrayList 优于 LinkedList | ArrayList 优于 LinkedList |
这是毋庸置疑的,实现了随机访问并且内部以数组形式存储数据的 ArrayList 拥有明显的优势。
删除数据
分别从头部、尾部和随机位置获取数据,初始的列表长度分别为1w、100w、1000w 来测试几种删除数据的性能,以吞吐量为判断依据,吞吐量单位是 每毫秒内操作数。得到的结果如下:

头部删除数据,LinkedList 吞吐量大于 ArrayList,得出结论:头部删除数据,LinkedList 性能优于 ArrayList

尾部删除数据,ArrayList 吞吐量大于 LinkedList,得出结论:尾部删除数据,ArrayList 性能优于 LinkedList

多次随机位置删除数据,ArrayList 吞吐量大于 LinkedList,得出结论:尾部删除数据,ArrayList 性能优于 LinkedList
综上,删除数据操作的结论如下
| 获取位置 | 列表长度100w | 列表长度1000w |
|---|---|---|
| 头部 | LinkedList 优于 ArrayList | LinkedList 优于 ArrayList |
| 尾部 | ArrayList 优于 LinkedList | ArrayList 优于 LinkedList |
| 多次随机位置 | ArrayList 优于 LinkedList | ArrayList 优于 LinkedList |
遍历数据
分别比较了 5 种遍历方式在1000、100w、1000w 长度的列表下的性能状况。
遍历方式一,原始形式的 for 循环
for(int i = 0;i<x;i++){
//do something
}
遍历方式二,增强形式的 for 循环
for(Integer i : arrayList){
// do something
}
遍历方式三,迭代器方式
Iterator iterator = arrayList.iterator();
while (iterator.hasNext()){
// do something
}
遍历方式四,forEach 方式
arrayList.forEach(integer -> {
// do something
});
遍历方式五,stream 方式
正常来讲,stream 后面再接 forEach 是不太正确的测试方式,一般 stream 都会配合 map、filter 等操作来进行筛选、计算等。这里为了方面测试,姑且先这个写了。
arrayList.stream().forEach(integer -> {
// do something
});
ArrayList 这 5 种方式遍历的性能

LinkedList 这 5 种方式遍历的性能

比较这五种方式下 ArrayList 和 LinkedList 的性能


LinkedList 只有在头部插入和删除数据频繁的时候才有优势,但是能找到这种应用场景似乎也不容易找到。如此看来,我们在程序中用到列表就随手 new 一个 ArrayList 倒也很有道理。
不要吝惜你的「推荐」呦
本文中的测试使用 JMH 基准测试完成的,图表是用 Excel 做的,如果需要源码和 Excel 文件,请在公众号内回复关键词 「jmh」
欢迎关注,不定期更新本系列和其他文章
古时的风筝 ,进入公众号可以加入交流群

基准测试了 ArrayList 和 LinkedList ,发现我们一直用 ArrayList 也是没什么问题的的更多相关文章
- 深入理解java中的ArrayList和LinkedList
杂谈最基本数据结构--"线性表": 表结构是一种最基本的数据结构,最常见的实现是数组,几乎在每个程序每一种开发语言中都提供了数组这个顺序存储的线性表结构实现. 什么是线性表? 由0 ...
- ArrayList与LinkedList比较
ArrayList与LinkedList比较 1.实现方式 ArrayList内部结构为数组,定义如下: /** * The array buffer into which the elements ...
- Java自学-集合框架 ArrayList和LinkedList的区别
ArrayList和LinkedList的区别 步骤 1 : ArrayList和LinkedList的区别 ArrayList ,插入,删除数据慢 LinkedList, 插入,删除数据快 Arra ...
- Java中ArrayList与LinkedList的区别
Java中ArrayList与LinkedList的区别 一般大家都知道ArrayList和LinkedList的区别: 1. ArrayList的实现是基于数组,LinkedList的实现是基于双向 ...
- 浅谈Vector、ArrayList、LinkedList
下图是Collection的类继承图 从图中可以看出:Vector.ArrayList.LinkedList这三者都实现了List 接口.所有使用方式也很相似,主要区别在于实现方式的不同,所以对不同的 ...
- Java基础——ArrayList与LinkedList(一)
一.定义 ArrayList和LinkedList是两个集合类,用于储存一系列的对象引用(references). 引用的格式分别为: ArrayList<String> list = n ...
- Java中ArrayList和LinkedList的性能分析
ArrayList和LinkedList是Java集合框架中经常使用的类.如果你只知道从基本性能比较ArrayList和LinkedList,那么请仔细阅读这篇文章. ArrayList应该在需要更多 ...
- Java ArrayList,LinkedList使用
1.ArrayList底层采用数组实现,当使用不带参数的构造方法生成ArrayList对象时,实际上回在底层生成一个长度为10的Object类型数组. 2.如果增加的元素个数超过10个,那么Array ...
- JAVA集合一:ArrayList和LinkedList
JAVA集合一:ArrayList和LinkedList 参考链接: HOW2J.CN 前言 这几篇博客重点记录JAVA的几个重要的集合框架:ArrayList.LinkedList.HashMap. ...
随机推荐
- C#操作SQLServer的一个简单封装
class DBHandler { //SqlConnection数据库连接对象 private SqlConnection localConnection = null; //构造函数中初始化连接对 ...
- JS中3种风格的For循环有什么异同?
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者.原文出处:https://blog.bitsrc.io/3-flavors-of-the-for-loop-i ...
- kafka删除弃用的groupid
登录zookeeper客户端 cd zookeeper-3.4.10 sh zkCli.sh 查看groupid信息 [zk:localhost:2181(CONNECTED) 1] ls /cons ...
- Linux虚拟机--进入MySQL报错的解决办法
在Linux安装MySQL有时候会出现 [mysql]ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/ ...
- .Net Core 跨平台:一个简单程序的多平台(windows、Linux、osx)发布
.Net Core 跨平台:一个简单程序的多平台(windows.Linux.osx)发布 .Net Core 3.0 已于2019年9月23日发布了,包含了一些新特性,具体参见Announcing ...
- c#学习路线应该靠谱
因为学c/c++,找不到工作.想转c#,搜索得到的学习路线 C#入门经典 C#数据库入门经典 C#高级编程 ADO.net高级编程 基础的东西搞明白之后,可以学习设计模式,C#设计模式 你是说深入的书 ...
- python教程 - 猿说python
一.简介 知识改变命运,程序改变世界.互联网时代潜移默化的改变着我们的生活,伴随技术的进步,我想下一个时代应该属于人工智能和机器学习,属于python. pytho ...
- 设计模式之UML类图以及类间关系
类图是描述系统中的类,以及各个类之间的关系的静态视图.能够让我们在正确编写代码以前对系统有一个全面的认识.类图是一种模型类型,确切的说,是一种静态模型类型.类图表示类.接口和它们之间的协作关系. 以下 ...
- 完整的Android MVP开发之旅
开发背景 最近是在做一个与健身相关的APP,里面有训练器模块基本功能是按照特点动作的演示和描述来引导用户完成训练.在第一个版本时由于没接触过些类项目与功能花了几周的时间大概1500行代码才完成这个功能 ...
- jQuery常用方法(五)-jQuery CSS
JQuery CSS 方法说明 css( name ) 访问第一个匹配元素的样式属性. css( properties ) 把一个"名/值对"对象设置为所有匹配元素的样式属性. $ ...