Java中List效率的比较

简介:

  inkfish原创,请勿商业性质转载,转载请注明来源(http://blog.csdn.net/inkfish )。

  Java Collections Framework(JCF) 是Java SE中一个基本的类集,几乎所有的项目都会用到,其中的List 则是JCF中最最常用的一个接口。围绕List 接口,有很多实现,诸如常用的ArrayListLinkedListVectorStack ,还有Java5之后引入的CopyOnWriteArrayList ,也有不少List 的开源实现,如Apache commons-collections中的各类List(来源:http://blog.csdn.net/inkfish)

  这么多的List 实现,如何选择?他们的运行效率具体怎样?本篇文章将用具体的代码来检测其中最最常用的一些List 实现。(来源:http://blog.csdn.net/inkfish)

测试环境:
  处理器:Intel Core 2 Duo P8600 2.4GHz
  内存:2G
  硬盘:160G 7200rpm
  Java:SUN JDK 1.6.0_15
  开发环境:Eclipse 3.5
  第三方类库:Apache commons-lang 2.4、Apache commons-collections 3.2.1(来源:http://blog.csdn.net/inkfish)

主要测试对象:
  java.util.ArrayList;
  java.util.LinkedList;
  java.util.Stack;
  java.util.Vector;
  java.util.concurrent.CopyOnWriteArrayList;
  org.apache.commons.collections.FastArrayList;
  org.apache.commons.collections.list.TreeList;
(来源:http://blog.csdn.net/inkfish)

测试用例:
  1.测试List
   1.1顺序添加
   1.2随机插入
   1.3随机删除
   1.4随机访问
   1.5随机更新
   1.5顺序迭代
  2.测试List 在三种情况下的排序效率
   2.1初始时List 中元素已从小到大有序排列(最优情况)
   2.2初始时List 中元素已从大到小有序排列(最差情况)
   2.3初始时List 中元素随机排列,无序
  3.测试List 互相转换的效率
   3.1转化为TreeList
   3.2转化为ArrayList
   3.3转化为LinkedList
   3.4转化为CopyOnWriteArrayList
   3.5转化为Vector (来源:http://blog.csdn.net/inkfish)

测试代码: (来源:http://blog.csdn.net/inkfish)

package test; import static java.lang.System.out; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Stack; import java.util.Vector; import java.util.concurrent.CopyOnWriteArrayList; import org.apache.commons.collections.FastArrayList; import org.apache.commons.collections.list.TreeList; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.time.StopWatch; @SuppressWarnings("unchecked") public class ListPerformance { public static void main(String[] args) { ListPerformance test = new ListPerformance(10 * 10000); out.print(StringUtils.center("Test List Performance: loop=" + test.loop, 80, '-')); out.printf("/n%20s%10s%10s%10s%10s%10s%10s", "", "add", "insert", "remove", "get", "set", "iterator"); test.benchmark(new FastArrayList()); test.benchmark(new TreeList()); test.benchmark(new ArrayList()); test.benchmark(new LinkedList()); test.benchmark(new CopyOnWriteArrayList()); test.benchmark(new Vector()); test.benchmark(new Stack()); //2.测试排序 out.print("/n/n"); out.print(StringUtils.center("Test List sort Performance: loop=" + test.loop, 80, '-')); out.printf("/n%20s%10s%10s%10s", "", "optimize", "worst", "random"); test.benchmarkSort(new FastArrayList()); test.benchmarkSort(new TreeList()); test.benchmarkSort(new ArrayList()); test.benchmarkSort(new LinkedList()); //test.benchmarkSort(new CopyOnWriteArrayList());//UnsupportedOperationException test.benchmarkSort(new Vector()); test.benchmarkSort(new Stack()); //3.测试各种数据结构间转化 out.print("/n/n"); out.print(StringUtils.center("Test List convert Performance: loop=" + test.loop, 80, '-')); out.printf("/n%20s%10s%10s%10s%10s%10s", "", "Tree", "Array", "Linked", "CopyOnWrite", "Vector"); test.benchmarkConvert(new FastArrayList()); test.benchmarkConvert(new TreeList()); test.benchmarkConvert(new ArrayList()); test.benchmarkConvert(new LinkedList()); test.benchmarkConvert(new CopyOnWriteArrayList()); } /**测试循环次数*/ private int loop = 10000; public ListPerformance(int loop) { this.loop = loop; } public void benchmark(List list) { out.printf("/n%20s", list.getClass().getSimpleName()); int j; StopWatch watch = null; //1.测试顺序性能(Add) (watch = new StopWatch()).start(); for (int i = 0; i < loop; i++) { list.add(new Integer(i)); } watch.stop(); out.printf("%10d", watch.getTime()); //2.测试随机插入性能(Random insert) (watch = new StopWatch()).start(); for (int i = 0; i < loop; i++) { j = (int) (Math.random() * loop); list.add(j, new Integer(-j)); } watch.stop(); out.printf("%10d", watch.getTime()); //3.测试随机索引删除(Random remove) (watch = new StopWatch()).start(); for (int i = 0; i < loop; i++) { j = (int) (Math.random() * loop); list.remove(j); } watch.stop(); out.printf("%10d", watch.getTime()); //4.测试随机取数性能(Random get) (watch = new StopWatch()).start(); for (int i = 0; i < loop; i++) { j = (int) (Math.random() * loop); list.get(j); } watch.stop(); out.printf("%10d", watch.getTime()); //5.测试随机更新性能(Random set) (watch = new StopWatch()).start(); for (int i = 0; i < loop; i++) { j = (int) (Math.random() * loop); list.set(j, j); } watch.stop(); out.printf("%10d", watch.getTime()); //6.测试迭代性能(Iterator) (watch = new StopWatch()).start(); Iterator<Object> iter = list.iterator(); while (iter.hasNext()) { iter.next(); } watch.stop(); out.printf("%10d", watch.getTime()); } public void benchmarkConvert(List list) { out.printf("/n%20s", list.getClass().getSimpleName()); StopWatch watch = null; //1.转TreeList (watch = new StopWatch()).start(); new TreeList(list); watch.stop(); out.printf("%10d", watch.getTime()); //2.转ArrayList (watch = new StopWatch()).start(); new ArrayList(list); watch.stop(); out.printf("%10d", watch.getTime()); //3.转LinkedList (watch = new StopWatch()).start(); new LinkedList(list); watch.stop(); out.printf("%10d", watch.getTime()); //4.转CopyOnWriteArrayList (watch = new StopWatch()).start(); new CopyOnWriteArrayList(list); watch.stop(); out.printf("%10d", watch.getTime()); //5.转Vector (watch = new StopWatch()).start(); new Vector(list); watch.stop(); out.printf("%10d", watch.getTime()); } public void benchmarkSort(List list) { out.printf("/n%20s", list.getClass().getSimpleName()); StopWatch watch = null; //1.顺序List for (int i = 0; i < loop; i++) { list.add(new Integer(i)); } (watch = new StopWatch()).start(); Collections.sort(list); watch.stop(); out.printf("%10d", watch.getTime()); //2.逆序List for (int i = loop - 1; i > 0; i--) { list.add(new Integer(i)); } (watch = new StopWatch()).start(); Collections.sort(list); watch.stop(); out.printf("%10d", watch.getTime()); //3.随机顺序List for (int i = 0, j = 0; i < loop; i++) { j = (int) (Math.random() * loop); list.add(new Integer(j)); } (watch = new StopWatch()).start(); Collections.sort(list); watch.stop(); out.printf("%10d", watch.getTime()); } }

测试结果: (来源:http://blog.csdn.net/inkfish)

-----------------------Test List Performance: loop=100000----------------------- add insert remove get set iterator FastArrayList 16 8609 8360 15 47 0 TreeList 110 187 156 47 110 78 ArrayList 15 8313 8344 0 15 0 LinkedList 47 50110 80671 59016 55391 78 CopyOnWriteArrayList 54016 484003 370891 16 105406 0 Vector 15 8266 8328 0 16 0 Stack 31 8281 8266 0 16 0 --------------------Test List sort Performance: loop=100000--------------------- optimize worst random FastArrayList 47 78 110 TreeList 15 47 110 ArrayList 32 47 78 LinkedList 15 109 125 Vector 0 63 94 Stack 16 46 78 -------------------Test List convert Performance: loop=100000------------------- Tree Array LinkedCopyOnWrite Vector FastArrayList 0 0 0 0 0 TreeList 0 0 0 0 0 ArrayList 0 0 0 0 0 LinkedList 0 0 0 0 0 CopyOnWriteArrayList 0 0 0 0 0

结论:
  1.随机插入、随机删除操作中,用TreeList 效率最高;
  2.在只需要追加、迭代的环境下,LinkedList 效率最高;
  3.平均效率来讲,ArrayList 相对平衡,但如果海量随机操作,还是会造成性能瓶颈;
  4.CopyOnWriteArrayList 因为线程安全的原因,致使性能降低很多,所以慎用;
  5.Vector 没有传说中那么低的效率;
  6.让Stack 来做List 的事可以,不过语义上Stack 不应该做过多的List 的事情;
  7.在排序中,ArrayList 具有最好的性能,TreeList 平均性能也不错,LinkedList 的排序效率受元素初始状态的影响很大。
  8.各种List 间转换几乎没有时间损耗。(来源:http://blog.csdn.net/inkfish)

目录
相关文章
|
7月前
|
存储 安全 Java
【Java集合类面试二十五】、有哪些线程安全的List?
线程安全的List包括Vector、Collections.SynchronizedList和CopyOnWriteArrayList,其中CopyOnWriteArrayList通过复制底层数组实现写操作,提供了最优的线程安全性能。
|
7月前
|
Java
【Java集合类面试二十三】、List和Set有什么区别?
List和Set的主要区别在于List是一个有序且允许元素重复的集合,而Set是一个无序且元素不重复的集合。
|
7月前
|
存储 Java
Java学习笔记 List集合的定义、集合的遍历、迭代器的使用
Java学习笔记 List集合的定义、集合的遍历、迭代器的使用
108 4
|
5月前
|
安全 Java 程序员
深入Java集合框架:解密List的Fail-Fast与Fail-Safe机制
本文介绍了 Java 中 List 的遍历和删除操作,重点讨论了快速失败(fail-fast)和安全失败(fail-safe)机制。通过普通 for 循环、迭代器和 foreach 循环的对比,详细解释了各种方法的优缺点及适用场景,特别是在多线程环境下的表现。最后推荐了适合高并发场景的 fail-safe 容器,如 CopyOnWriteArrayList 和 ConcurrentHashMap。
104 5
|
5月前
|
Java 程序员 编译器
Java|如何正确地在遍历 List 时删除元素
从源码分析如何正确地在遍历 List 时删除元素。为什么有的写法会导致异常,而另一些不会。
102 3
|
5月前
|
Java 程序员
Java|List.subList 踩坑小记
不应该仅凭印象和猜测,就开始使用一个方法,至少花一分钟认真读完它的官方注释文档。
56 1
|
7月前
|
Java 数据库
成功解决:java.sql.SQLSyntaxErrorException: Unknown column ‘origin_name‘ in ‘field list‘
这篇文章讲述了作者在使用SpringBoot和Mybatis-plus时遇到的一个数据库字段映射问题,即SQLSyntaxErrorException错误,原因是实体类字段和数据库字段不匹配。文章提供了两种解决方法:一是关闭自动驼峰命名转换配置,二是修改数据库字段以匹配实体类字段,最终成功解决了问题。
成功解决:java.sql.SQLSyntaxErrorException: Unknown column ‘origin_name‘ in ‘field list‘
|
7月前
|
存储 安全 Java
java集合框架复习----(2)List
这篇文章是关于Java集合框架中List集合的详细复习,包括List的特点、常用方法、迭代器的使用,以及ArrayList、Vector和LinkedList三种实现类的比较和泛型在Java中的使用示例。
java集合框架复习----(2)List
|
7月前
|
存储 安全 Java
java集合框架复习----(4)Map、List、set
这篇文章是Java集合框架的复习总结,重点介绍了Map集合的特点和HashMap的使用,以及Collections工具类的使用示例,同时回顾了List、Set和Map集合的概念和特点,以及Collection工具类的作用。
java集合框架复习----(4)Map、List、set
|
8月前
|
Java API 存储
Java如何对List进行排序?
【7月更文挑战第26天】
340 9
Java如何对List进行排序?

热门文章

最新文章