深入浅析ArrayList 和 LinkedList的执行效率比较

所属分类: 软件编程 / java 阅读数: 24
收藏 0 赞 0 分享

一、概念:

    一般我们都知道ArrayList* 由一个数组后推得到的 List。作为一个常规用途的对象容器使用,用于替换原先的 Vector。允许我们快速访问元素,但在从列表中部插入和删除元素时,速度却嫌稍慢。一般只应该用ListIterator 对一个 ArrayList 进行向前和向后遍历,不要用它删除和插入元素;与 LinkedList 相比,它的效率要低许多LinkedList 提供优化的顺序访问性能,同时可以高效率地在列表中部进行插入和删除操作。但在进行随机访问时,速度却相当慢,此时应换用 ArrayList。

二、测试

    本来自己写了一些测试类想测试下ArrayList和LinkedList的性能比较,发现怎么写都差强人意,今天在《Thinking in Java》中看到了这样的一段代码,个人觉得写得不赖。

public class ListPerformance
{
 private static final int REPS = 100;
 private abstract static class Tester//内部抽象类,作为List测试。
 {
  String name;
  int size;
  Tester(String name, int size)
  {
   this.name = name;
   this.size = size;
  }
  abstract void test(List a);
 }
 private static Tester[] tests = {new Tester("get", 300)//一个测试数组,存储get(随机取)、iteration(顺序遍历)、insert(中间插入)、remove(随机删除)
 {
  void test(List a)
  {
   for (int i = 0; i < REPS; i++) {
    for (int j = 0; j < a.size(); j++) {
     a.get(j);
    }
   }
  }
 }, new Tester("iteration", 300)
 {
  void test(List a)
  {
   for (int i = 0; i < REPS; i++) {
    Iterator it = a.iterator();
    while (it.hasNext()) it.next();
   }
  }
 }, new Tester("insert", 1000)
 {
  void test(List a)
  {
   int half = a.size() / 2;
   String s = "test";
   ListIterator it = a.listIterator(half);
   for (int i = 0; i < size * 10; i++) {
    it.add(s);
   }
  }
 }, new Tester("remove", 5000)
 {
  void test(List a)
  {
   ListIterator it = a.listIterator(3);
   while (it.hasNext()) {
    it.next();
    it.remove();
   }
  }
 },
          };
 public static void test(List a)
 {
  System.out.println("Testing " + a.getClass().getName());//输出测试的类名称
  for (int i = 0; i < tests.length; i++) {
   fill(a, tests[i].size);//填充空集合
   System.out.print(tests[i].name);
   long t1 = System.currentTimeMillis();
   tests[i].test(a);//进行测试
   long t2 = System.currentTimeMillis();
   System.out.print(":" + (t2 - t1)+" ms ");
  }
 }
 public static Collection fill(Collection c, int size)
 {
  for (int i = 0; i < size; i++) {
   c.add(Integer.toString(i));
  }
  return c;
 }
 public static void main(String[] args)
 {
  test(new ArrayList());
  System.out.println();
  test(new LinkedList());
 }
}

三、总结

    首先,真的夸一下,这段代码写得真是好啊,无论是内部类的应用还是对面向对象的认识,都考虑的恰到好处,哎,我什么时候才能写出这么棒的代码啊。

    测试结果每次都有些许的差异,但不难得出以下的结论:

        1、在 ArrayList 中进行随机访问(即 get())以及循环反复是最划得来的 。原因在于,ArrayList是基于数组而来的,所以每个元素都有其对应的index,所以随机定位一个元素要快捷的多。

        2、在 LinkedList 中进行顺序访问、插入、删除动作的话还是比较高效的。原因在于,插入、删除的话对于LinkedList来说只需要改变其排列的一个node结点就可以了,而对于ArrayList来说删除一个元素,需要不断把后面的元素移到前面的位置上。

        3、至于顺序访问,之前一直认为ArrayList 基于数组排列,在内存中是连续排列的,应该会快得多,然后多次测试发现并不是想象的那样,或者说ArrayList没有表现出它该有的优势,甚至还不如LinkedList的访问速度。原因在于:LinkedList 提供了优化的顺序访问性能。

以上所述是小编给大家介绍的ArrayList 和 LinkedList的执行效率比较,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

更多精彩内容其他人还在看

Java的面向对象编程基本概念学习笔记整理

这篇文章主要介绍了Java的面向对象编程基本概念学习笔记整理,包括类与方法以及多态等支持面向对象语言中的重要特点,需要的朋友可以参考下
收藏 0 赞 0 分享

Eclipse下编写java程序突然不会自动生成R.java文件和包的解决办法

这篇文章主要介绍了Eclipse下编写java程序突然不会自动生成R.java文件和包的解决办法 的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

基于Java实现杨辉三角 LeetCode Pascal's Triangle

这篇文章主要介绍了基于Java实现杨辉三角 LeetCode Pascal's Triangle的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

Java中Spring获取bean方法小结

Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架,如何在程序中获取Spring配置的bean呢?下面通过本文给大家介绍Java中Spring获取bean方法小结,对spring获取bean方法相关知识感兴趣的朋友一起学习吧
收藏 0 赞 0 分享

如何计算Java对象占用了多少空间?

在Java中没有sizeof运算符,所以没办法知道一个对象到底占用了多大的空间,但是在分配对象的时候会有一些基本的规则,我们根据这些规则大致能判断出来对象大小,需要的朋友可以参考下
收藏 0 赞 0 分享

剖析Java中的事件处理与异常处理机制

这篇文章主要介绍了Java中的事件处理与异常处理机制,讲解Java是如何对事件或者异常作出响应以及定义异常的一些方法,需要的朋友可以参考下
收藏 0 赞 0 分享

详解Java的Struts2框架的结构及其数据转移方式

这篇文章主要介绍了详解Java的Struts2框架的结构及其数据转移方式,Struts框架是Java的SSH三大web开发框架之一,需要的朋友可以参考下
收藏 0 赞 0 分享

Java封装好的mail包发送电子邮件的类

本文给大家分享了2个java封装好的mail包发送电子邮件的类,并附上使用方法,小伙伴们可以根据自己的需求自由选择。
收藏 0 赞 0 分享

在Java的Struts中判断是否调用AJAX及用拦截器对其优化

这篇文章主要介绍了在Java的Struts中判断是否调用AJAX及用拦截器对其优化的方法,Struts框架是Java的SSH三大web开发框架之一,需要的朋友可以参考下
收藏 0 赞 0 分享

java多线程Future和Callable类示例分享

JAVA多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。今天我们就来研究下Future和Callab
收藏 0 赞 0 分享
查看更多