基准测试了 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. ...
随机推荐
- 【linux】【FastDFS】FastDFS安装
前言 FastDFS是一个开源的轻量级分布式文件系统,由跟踪服务器(tracker server).存储服务器(storage server)和客户端(client)三个部分组成,主要解决了海量数据存 ...
- 谁是狸猫谁是太子?--戏说java构造器
故事背景 <狸猫换太子>在我国民间文学中很出名,故事剧情大致如下:北宋第三位皇帝宋真宗赵恒年长无子,他的两个妃子刘妃与李妃同时怀了身孕.真宗召见二人,各赐信物,并声明哪个生了儿子就立谁为皇 ...
- 关于瀑布流的布局原理分析(纯CSS瀑布流与JS瀑布流)
瀑布流 又称瀑布流式布局,是比较流行的一种网站页面布局方式.即多行等宽元素排列,后面的元素依次添加到其后,等宽不等高,根据图片原比例缩放直至宽度达到我们的要求,依次按照规则放入指定位置. 为什么使用瀑 ...
- 部署Tomcat 环境
部署Tomcat 环境(mysql+tomcat+jdk) 1.下载Tomcat 软件包 2.通过xftp创建root 连接,然后将Tomcat 软件包拖拽到/opt目录下 3.在xshell 上ro ...
- 使用docker安装mysql并连接
1.查找镜像: docker search mysql 也可以去官网查看镜像tag,选择自己需要的版本,否则会下载最新版本:https://hub.docker.com/_/mysql/ 2.下载镜像 ...
- SpringBootSecurity学习(01)网页版登录入门介绍
Web应用安全管理 Web应用的安全管理,主要包括两个方面的内容,一个是用户身份的认证,即用户登录的设计,二是用户授权,即一个用户在一个应用系统中能够执行哪些操作的权限管理.权限管理的设计一般使用角色 ...
- Spring 梳理 - javaConfig在App和webApp中的应用
package com.dxz.demo.configuration; import org.springframework.context.annotation.Configuration; @Co ...
- 【SQL server基础】判断数据库、表格、视图、存储过程、函数书否存在
库是否存在 if exists(select * from master..sysdatabases where name=N'库名') print 'exists' else print 'not ...
- 蓝松短视频SDK基本功能免费列表
下载地址:https://github.com/LanSoSdk/LanSoEditor_common 功能免费. 个人和公司都可以商用,不需要和我们说明. 直接下载, 直接去用既可. 完全不需要和我 ...
- ELK 学习笔记之 Logstash安装
Logstash安装: https://www.elastic.co/downloads/logstash 下载解压: tar –zxvf logstash-5.6.1.tar.gz 在/usr/lo ...