2019独角兽企业重金招聘Python工程师标准>>>

原文链接地址

最近在看数据结构,发现这个东西不错,记录下来,以便分享!        
           ArrayList内部是使用可増长数组实现的,所以是用get和set方法是花费常数时间的,但是如果插入元素和删除元素,除非插入和删除的位置都在表末尾,否则代码开销会很大,因为里面需要数组的移动。
           LinkedList是使用双链表实现的,所以get会非常消耗资源,除非位置离头部很近。但是插入和删除元素花费常数时间。
           我们来看下面一个例子:
           public void listTest1(List<Integer> list, int n) {
                   list.clear();
           for (int i=0; i<n; i++) {
            list.add(i);
          }
           }
          上面这个例子,不论是ArrayList还是LinkedList运行的时间都是O(N),因为每次的操作都是在表末尾进行的。如果我们把add方法换成下面的呢!
           list.add(0, i);
           该完之后,对于LinkedList运行时间是O(N),但是对于ArrayList则是O(N^2),一位每次添加都需要移动数组,运行时间是O(N)
        再看看下面的这个例子:计算list中数据之和
        public int listSum(List<Integer> list) {
        int sum = 0;
        for (int i=0; i<list.size(); i++) {
            sum += list.get(i);
        }
        return sum;
    }
       这个例子对于ArrayList运行时间是O(N),但是对于LinkedList运行时间就是O(N^2),但是如果我们使用增强for循环,那么就会不一样。代码如下:
       public int listSum2(List<Integer> list) {
        int sum = 0;
        for (Integer i: list) {
            sum += i;
        }
        return sum;
    }
       这样无论是ArrayList和LinkedList其运行时间都是O(N),因为迭代器会有效的从一项到下一项推进。
       下面我们说一个remove方法
        问题:将一个表中的所有偶数项全部删除,要求不能创建新表。
       最简单的就是,进行for遍历,然后取出数值判断是否是偶数,如果是就删除,代码如下:
       public static void removeEvensOne(List<Integer> list) {
        for (int i=0; i<list.size(); i++) {
            if (list.get(i) % 2 == 0) {
                list.remove(i); //移除的是i位置上的元素
            }
        }
    }
       我们来分析一下,如果传入的参数是Arraylist,那么效率一定会很低,我做了一下测试,创建一个400000项的ArrayList,程序运行时间大约是16s。想着如果传入的是LinkedList是否会很快,答案是否!对于LinkedList运行时间至少要一分多钟,这就奇怪了LinkedList不是删除操作是常数时间吗。我们仔细看看这里面需最消耗时间的是list.get(i)和list.remove(i),首先对于LinkedList的get()操作时间复杂度是O(N),对于remove(i)时间,LinkedList需要到达位置i,那么如何到达,只能是从第一个元素一直搜索下去,其时间复杂读也是O(N),所以对于这个程序LinkedList消耗的时间要比ArrayList多的多。
     既然用for循环需要.get(i),那我们使用增强for循环好了,代码如下:
     public static void removeEvensThree(List<Integer> list) {
        for (Integer i: list) {
            if (i%2 == 0) {
                list.remove(i); //移除的是元素i
            }
        }
     }
     运行一下,抛出异常java.util.ConcurrentModificationException。也就是说list.remove()破坏了增强for循环,这个方法不行,但是它给了我们一个思路:在迭代器找到一个偶数时,我们可以使用迭代器来删除这个偶数值。我们使用Iterator迭代器,代码如下:
     public static void removeEvensTwo(List<Integer> list) {
        Iterator<Integer> it = list.iterator();
        while (it.hasNext()) {
            if (it.next() % 2 == 0) {
                it.remove();
            }
        }
    }
       这个代码中我们不需要查找,还是使用400000个元素的list进行测试,ArrayList没有什么变化,时间依然是16s,这是因为即使迭代器位于要删除的节点上,删除之后元素还是要移动。对于LinkedList花费的时间小于1s。
        从上面我们可以看出:ArrayList虽然get和set快,但是remove却很慢。对于LinkedList虽然删除和插入很快,但是如果期间使用了get那么一样会很慢。如果是有大量的删除操作我们还是使用Iterator迭代器比较好。

原文地址http://www.exceptionhelp.com

转载于:https://my.oschina.net/u/1013545/blog/261061

正确使用ArrayList和LinkedList相关推荐

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

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

  2. ArrayList、LinkedList、 Vector、Map 用法比较

    ArrayList和Vector是采用数组方式存储数据,此数组元素总数大于实际存储的数据个数以便增加和插入元素,二者都允许直接序号索引元素,但是插入数据要移动数组元素等内存操作,所以它们索引数据快.插 ...

  3. java温故笔记(二)java的数组HashMap、ConcurrentHashMap、ArrayList、LinkedList

    为什么80%的码农都做不了架构师?>>>    HashMap 摘要 HashMap是Java程序员使用频率最高的用于映射(键值对)处理的数据类型.随着JDK(Java Develo ...

  4. java面试题29 牛客 以下关于集合类ArrayList、LinkedList、HashMap描述

    java面试题29 牛客 以下关于集合类ArrayList.LinkedList.HashMap描述错误的是() A HashMap实现Map接口,它允许任何类型的键和值对象,并允许将null用作键或 ...

  5. java stack 类 效率_Java中ArrayList、LinkedList、Vector、Stack的比较

    一.介绍 先回顾一下List的框架图 由图中的继承关系,可以知道,ArrayList.LinkedList.Vector.Stack都是List的四个实现类. AbstractList是一个抽象类,它 ...

  6. 递增的整数序列链表的插入_程序员:数据结构——链表List、ArrayList、LinkedList...

    抽象数据类型ADT 是带有一组操作的一些对象的集合 一种特别的抽象类型--表ADT 什么是一个表呢? 最简单的一个整数表 -> 由一群整数构成的一个数组,可以看做是一张表 //表的简单数组实现 ...

  7. [Java] ArrayList、LinkedList、Vector的区别

    版权声明:请尊重个人劳动成果,转载注明出处,谢谢! 首先我们来看一下继承关系: 我们可以看出ArrayList.LinkedList.Vector都实现了List的接口.  接下来分别看一下三个数据结 ...

  8. ArrayList和LinkedList的区别以及优缺点

    ArrayList和LinkedList的区别以及优缺点 (在面试的时候经常会提问,谈一谈以你对ArrayList和LinkedList的区别以及优缺点,今天做一下笔记,方便以后查看,个人理解,不一定 ...

  9. 移除集合效率高还是add高_HashMap存取效率高原因、ArrayList和LinkedList区别、JAVA实现链表的基本功能...

    一.HashMap存取效率高原因 1.Hash 也叫散列.哈希. 主要用于信息安全领域中的算法,把长度不同的信息转化为杂乱的128位的编码,找到一种数据内容与地址之间的映射关系. 注意:不同的输入可能 ...

最新文章

  1. C和C++安全编码笔记:总结
  2. 北斗导航 | GPS 信号频谱分析
  3. 【uni-app】在新窗口中打开链接
  4. 学成在线案例——黑马程序员pink老师\思路讲解\完整源代码
  5. 命令行查看Memcached运行状态
  6. 【转】一个新的UIButtonMessage 给NGUI,使用委托,自动选择Receiver提供的方法
  7. 关于ContentResolver
  8. node.js连接数据库(mysql)
  9. SkewTransform
  10. eclipse快速导包快捷键_【IntelliJ IDEA mac新手入门】IDEA如何快速搭建Java开发环境...
  11. 短信接口怎么对接?看完这篇文章你就知道了!
  12. 使用Java抓取解析汽车之家车型配置数据
  13. OpManager引领智能运维未来的发展方向
  14. 前端加载shapefile数据
  15. 可控硅失效现象_可控硅常见心理问题损坏社会经济现象的介绍和分析
  16. u盘文件名乱码linux,U盘文件夹变空文件夹的文件名乱码的修复方法
  17. ShowWindow函数
  18. 如何使用PS修改图片背景
  19. 关于举办“2020·中国边缘计算企业20强”榜单评选通知
  20. 【Kanzi】1:android编译环境配置

热门文章

  1. ajax请求成功后返回值如何赋值给js变量
  2. 【分享】免费建立自己的站点
  3. 我的敏捷、需求分析、UML、软件设计电子书 - 下载(持续更新中)
  4. 教育院校公共机房虚拟桌面解决方案
  5. 关于ArcGIS Mobile回传数据中常遇到的问题整理!
  6. 《『若水新闻』客户端开发教程》——04.设计新闻分类UI(2)
  7. android源码解析------Media多媒体framework层分析
  8. 【iOS开发】在一个Xcode页面建立多个工程
  9. 制作内网yum源 同步阿里的源
  10. IntelliJ IDEA 14 license key gen