前言:

在我们平常开发中难免会用到List集合来存储数据,一般都会选择ArrayList和LinkedList,以前只是大致知道ArrayList查询效率高LinkedList插入删除效率高,今天来实测一下。

先了解一下List

  List列表类,顺序存储任何对象(顺序不变),可重复。

  List是继承于Collection的接口,不能实例化。实例化可以用:

  • ArrayList(实现动态数组),查询快(随意访问或顺序访问),增删慢。整体清空快,线程不同步(非线程安全)。数组长度是可变的百分之五十延长
  • LinkedList(实现链表),查询慢,增删快。
  • Vector(实现动态数组),都慢,被ArrayList替代。长度任意延长。线程安全(同步的类,函数都是synchronized)
  • Stack(实现堆栈)继承于Vector,先进后出。

List基本操作

  • 插入:add()
  • 查找:get()
  • 删除:remove(int index)
  • 修改:set()
  • 清空表:clear()
  • 遍历:用Iterator迭代器遍历每个元素

ArrayList、LinkedList性能对比

为了很好的对比效率,直接写个测试程序看下运行结果

模拟5w条数据指定插入第一位,然后查询全部,循环删除第一位,下面是测试ArrayList函数

private void testArrayList(){
ArrayList<String> list=new ArrayList<>();
int maxTestCount=50000; //测试添加
long start =System.currentTimeMillis(); for(int i =0;i<maxTestCount;i++){
list.add(0,String.valueOf(i));
} long end =System.currentTimeMillis(); Log.e(TAG,"ArrayList add cost time :"+(end-start)); //测试查询
start =System.currentTimeMillis(); for(int i =0;i<maxTestCount;i++){
list.get(i);
} end =System.currentTimeMillis(); Log.e(TAG,"ArrayList get cost time :"+(end-start)); //测试查询
start =System.currentTimeMillis(); for(int i =maxTestCount;i>0;i--){
list.remove(0);
} end =System.currentTimeMillis(); Log.e(TAG,"ArrayList remove cost time :"+(end-start)); }

测试LinkedList函数

private void testLinkedList(){
LinkedList<String> list=new LinkedList<>();
int maxTestCount=50000; //测试添加
long start =System.currentTimeMillis(); for(int i =0;i<maxTestCount;i++){
list.add(0,String.valueOf(i));
} long end =System.currentTimeMillis(); Log.e(TAG,"LinkedList add cost time :"+(end-start)); //测试查询
start =System.currentTimeMillis(); for(int i =0;i<maxTestCount;i++){
list.get(i);
} end =System.currentTimeMillis(); Log.e(TAG,"LinkedList get cost time :"+(end-start)); //测试查询
start =System.currentTimeMillis(); for(int i =maxTestCount;i>0;i--){
list.remove(0);
} end =System.currentTimeMillis(); Log.e(TAG,"LinkedList remove cost time :"+(end-start)); }

先后调用两个函数,看下运行结果

通过上面的运行结果可以大致得出以下结论:

  • ArrayList插入、删除效率明显低于LinkedList
  • ArrayList查询效率远远高于LinkedList

通过上面的结构是不是就可以认为插入删除频繁选择LinkedList,追求查询效率就选择ArrayList呢,我们先来分析一下效率差别的原因,这个就跟数据结构有关系了,可以参考一些数据结构中链表的知识,arraylist 顺序表,用数组的方式实现。想想数组要查询那个元素只给出其下标即可,所以才说arraylist随机访问多的场景比较合适。但是如果删除某个元素比如第 i 个元素,则要将 i 之后的元素都向前移一位以保证顺序表的正确,增加也是一样,要移动多个元素。要多次删除增加的话是很低效的。而LinkedList是双向链表,注意是链表。要查询只能头结点开始逐步查询,没有什么给出下标即可直接查询的便利,需要遍历。但是,如果要增加后删除一个元素的话,只需要改变其前后元素的指向即可,不需要像arraylist那样整体移动,所以才说多用于增删多的场合。

很感谢博友的建议与帮助,由于LinkedList查询只能从头结点开始逐步查询的,可以使用 iterator 的方式,就不用每次都从头结点开始访问,因为它会缓存当前结点的前后结点。实测查询效率与ArrayList没有太大差别

LinkedList<String> list = new LinkedList<>();
Iterator<String> it = list.iterator();
while(it.hasNext()){
String s = it.next();
}

List其他知识扩展

Vector 是矢量队列,和ArrayList一样,它也是一个动态数组,由数组实现。但是ArrayList是非线程安全的,而Vector是线程安全的。
Stack 是栈,它继承于Vector。它的特性是:先进后出(FILO, First In Last Out)。

总结:

通过运行结果和查阅资料基本上验证了ArrayList和LinkedList效率问题,有助于在以后的开发中根据实际场景选择合适的技术方案。

Java数据结构之LinkedList、ArrayList的效率分析的更多相关文章

  1. Java日常总结之LinkedList、ArrayList的效率分析

    前言: 在我们平常开发中难免会用到List集合来存储数据,一般都会选择ArrayList和LinkedList,以前只是大致知道ArrayList查询效率高LinkedList插入删除效率高,今天来实 ...

  2. java集合系列之ArrayList源码分析

    java集合系列之ArrayList源码分析(基于jdk1.8) ArrayList简介 ArrayList时List接口的一个非常重要的实现子类,它的底层是通过动态数组实现的,因此它具备查询速度快, ...

  3. java集合框架03——ArrayList和源码分析

    最近忙着替公司招人好久没写了,荒废了不好意思. 上一章学习了Collection的架构,并阅读了部分源码,这一章开始,我们将对Collection的具体实现进行详细学习.首先学习List.而Array ...

  4. java数据结构--array与ArrayList的区别

    ArrayList 内部是由一个array 实现的. 如果你知道array 和 ArrayList 的相似点和不同点,就可以选择什么时候用array 或者使用ArrayList , array 提供 ...

  5. java数据结构之列表——ArrayList,LinkedList,比较

    刚看完<数据结构与算法分析java语言描述>的第3章中的表,下面回忆下主要知识点,主要说明各列表之间的关系,以及各自的优缺点.其中牵涉到内部类和嵌套类. 1 Collection APIp ...

  6. Java基础-集合框架-ArrayList源码分析

    一.JDK中ArrayList是如何实现的 1.先看下ArrayList从上而下的层次图: 说明: 从图中可以看出,ArrayList只是最下层的实现类,集合的规则和扩展都是AbstractList. ...

  7. Java集合类学习-LinkedList, ArrayList, Stack, Queue, Vector

    Collection List 在Collection的基础上引入了有序的概念,位置精确:允许相同元素.在列表上迭代通常优于索引遍历.特殊的ListIterator迭代器允许元素插入.替换,双向访问, ...

  8. Java集合系列[1]----ArrayList源码分析

    本篇分析ArrayList的源码,在分析之前先跟大家谈一谈数组.数组可能是我们最早接触到的数据结构之一,它是在内存中划分出一块连续的地址空间用来进行元素的存储,由于它直接操作内存,所以数组的性能要比集 ...

  9. java数据结构之LinkedList

    一.LinkedList源码注释 //LinkedList源码 jdk版本1.8.0_121 public class LinkedList<E> extends AbstractSequ ...

随机推荐

  1. tp5数据库链接

    1在config/database.php中配置 1.1直接 return [ // 数据库类型 'type' => 'mysql', // 服务器地址 'hostname' => '12 ...

  2. Mybatis之占位符与拼接符

    1.占位符 1.1  含义: 在持久化框架中,为了将约束条件中的可变参数从sql中分离出来,在原有的参数位置使用特殊的标记来标记该位置,后期通过代码给sql传递参数(即实现sql与代码分离开).这个特 ...

  3. macOS packages安装时的降级处理

    一.降级安装 在制作macOS的pkg安装包时,一般新发布的程序版本会比旧版本更高.但是有的时候我们也希望在安装的时候,对程序的某些依赖库进行降级安装.比如高版本依赖库中出现了一些Bug,使用旧版本的 ...

  4. PhantomJS在Selenium中被标记为过时的应对措施

    今天使用PhantomJS时,Selenium提示PhantomJS被标记不赞成,我就蒙了.PhantomJS可是Headless浏览器中相当知名的一款,标记为过时,代表着将在未来版本摒弃掉这个支持. ...

  5. Callable与Runable接口 submit与execute区别

    execute(Runnable x) 没有返回值.可以执行任务,但无法判断任务是否成功完成. submit(Runnable x) 返回一个future.可以用这个future来判断任务是否成功完成 ...

  6. EF Core中的多对多映射如何实现?

    EF 6.X中的多对多映射是直接使用HasMany-HasMany来做的.但是到了EF Core中,不再直接支持这种方式了,可以是可以使用,但是不推荐,具体使用可以参考<你必须掌握的Entity ...

  7. SpringBoot整合dubbo

    Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和Spring框架无缝集成. 以上介绍来源于百度百科,具体dubbo相关可以自行查 ...

  8. IE8 兼容性总结

    rgba 颜色格式 IE8 不支持 rgba(0, 0, 0, .5) 这种颜色格式. 解决方案:可以利用一张半透明的 png 图片来兼容 IE8. flexbox 根据 caniuse 给出的数据, ...

  9. BZOJ.4515.[SDOI2016]游戏(树链剖分 李超线段树)

    BZOJ 洛谷 每次在路径上加的数是个一次函数,容易看出是树剖+李超线段树维护函数最小值.所以其实依旧是模板题. 横坐标自然是取个确定的距离标准.取每个点到根节点的距离\(dis[i]\)作为\(i\ ...

  10. 蓝桥杯 ——无重复组合——C++

    问题描述: 求任意长度的(ABCD.....)全部n=0,1,2 ....组合情况(n小于等于串的长度) 解决思路: 如果串的长度固定,n的值固定循环嵌套 在这里以深度优先形成一棵树,如下图: 源代码 ...