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 也是没什么问题的的更多相关文章

  1. 深入理解java中的ArrayList和LinkedList

    杂谈最基本数据结构--"线性表": 表结构是一种最基本的数据结构,最常见的实现是数组,几乎在每个程序每一种开发语言中都提供了数组这个顺序存储的线性表结构实现. 什么是线性表? 由0 ...

  2. ArrayList与LinkedList比较

    ArrayList与LinkedList比较 1.实现方式 ArrayList内部结构为数组,定义如下: /** * The array buffer into which the elements ...

  3. Java自学-集合框架 ArrayList和LinkedList的区别

    ArrayList和LinkedList的区别 步骤 1 : ArrayList和LinkedList的区别 ArrayList ,插入,删除数据慢 LinkedList, 插入,删除数据快 Arra ...

  4. Java中ArrayList与LinkedList的区别

    Java中ArrayList与LinkedList的区别 一般大家都知道ArrayList和LinkedList的区别: 1. ArrayList的实现是基于数组,LinkedList的实现是基于双向 ...

  5. 浅谈Vector、ArrayList、LinkedList

    下图是Collection的类继承图 从图中可以看出:Vector.ArrayList.LinkedList这三者都实现了List 接口.所有使用方式也很相似,主要区别在于实现方式的不同,所以对不同的 ...

  6. Java基础——ArrayList与LinkedList(一)

    一.定义 ArrayList和LinkedList是两个集合类,用于储存一系列的对象引用(references). 引用的格式分别为: ArrayList<String> list = n ...

  7. Java中ArrayList和LinkedList的性能分析

    ArrayList和LinkedList是Java集合框架中经常使用的类.如果你只知道从基本性能比较ArrayList和LinkedList,那么请仔细阅读这篇文章. ArrayList应该在需要更多 ...

  8. Java ArrayList,LinkedList使用

    1.ArrayList底层采用数组实现,当使用不带参数的构造方法生成ArrayList对象时,实际上回在底层生成一个长度为10的Object类型数组. 2.如果增加的元素个数超过10个,那么Array ...

  9. JAVA集合一:ArrayList和LinkedList

    JAVA集合一:ArrayList和LinkedList 参考链接: HOW2J.CN 前言 这几篇博客重点记录JAVA的几个重要的集合框架:ArrayList.LinkedList.HashMap. ...

随机推荐

  1. 将SpringBoot部署在外部tomcat中

    一,前言 在文章SpringBoot之简单入门中提到了,SpringBoot是内置一个tomcat容器的,但是如果要将SpringBoot部署在一个外部的tomcat,要怎么办呢?这就是本篇文章的目的 ...

  2. Xampp error:Port 80 in use by "Unable to open process" with PID 4

    今天打开Apache的时候报错: Port 80 in use by "Unable to open process" with PID 4 通过点击与“Apache”模块同一行上 ...

  3. SpringBoot官方文档学习(一)开发你的第一个Spring Boot应用

    一些准备工作: 本节介绍如何开发一个简单的“ Hello World!” Web应用程序,该应用程序重点介绍Spring Boot的一些关键功能.我们使用Maven来构建该项目,因为大多数IDE都支持 ...

  4. CDH 5.9.3 集群配置

    -----------------------------------------集群规划------------------------------------------ hostname ip ...

  5. Hadoop点滴-Hadoop的IO

    Hadoop自带一套原子操作用于数据的I/O操作. 如果系统中需要处理的数据量达到Hadoop的处理极限时,数据被损害的概率还是很高的 检测数据是否被损害的常见措施是,在数据第一次被引进系统时,计算校 ...

  6. android实现emoji输入

    学android也有一段时间, 一直都是自己摸索, 各种上网查资料, 也明白了不能一味去索取有时间也要分享一些自己的心得 . 最近几天都在写关于android emoji输入的小例子,网上有不少源码还 ...

  7. 链表常见的题型(java实现)

    链表是面试中最常见的一种题型,因为他的每个题的代码短,短短的几行代码就可以体现出应聘者的编码能力,所以它也就成为了面试的重点. 链表常见的操作有1.打印链表的公共部分,2.删除链表的倒数第K个节点,3 ...

  8. Angular 元素拖拽

    拖动元素到指定区域 拖放的同时传递数据 1. 安装 ng2-drag-drop npm install ng2-drag-drop --save 2. 模板中配置可拖拽元素 // drag.compo ...

  9. android系统中对ffmpeg封装最好的免费SDK

    android系统中对ffmpeg封装最好的免费SDK; 无论个人还是公司,都免费商用, 欢迎下载. https://github.com/LanSoSdk/LanSoEditor_common 可能 ...

  10. POJ 2533——Longest Ordered Subsequence(DP)

    链接:http://poj.org/problem?id=2533 题解 #include<iostream> using namespace std; ]; //存放数列 ]; //b[ ...