Java Collections Framework - Java集合框架之List篇 ArrayList与LinkedList等的性能比较

Java Collections Framework的List集合类主要有ArrayList,LinkedList,Vector,Stack等。本文主要对它们作一个比较,说明它们的异同点以及性能上的区别等。


概要
我们在 Java Collections Framework - Java集合框架List,Map,Set等全面介绍之概要篇  一文中对Java集合框架(Java Collections Framework)做了一个比较全面的介绍。

该文粗略地介绍了List集合的概念定义等。

List集合
List继承自Collection接口。List是一种有序集合,List中的元素可以根据索引(顺序号:元素在集合中处于的位置信息)进行取得/删除/插入操作。
跟Set集合不同的是,List允许有重复元素。对于满足e1.equals(e2)条件的e1与e2对象元素,可以同时存在于List集合中。当然,也有List的实现类不允许重复元素的存在。
同时,List还提供一个listIterator()方法,返回一个ListIterator接口对象,和Iterator接口相比,ListIterator添加元素的添加,删除,和设定等方法,还能向前或向后遍历。

List跟Collection的关系:
java.util.Collection [I]
+--java.util.List [I]
   +--java.util.ArrayList [C]
   +--java.util.LinkedList [C]
   +--java.util.Vector [C]
      +--java.util.Stack [C]

List接口的实现类主要有ArrayList,LinkedList,Vector,Stack等。

本文主要对上面提到的几个类作一个比较,说明它们的异同点以及性能上的区别等。


ArrayList,LinkedList,Vector,Stack的相同点
ArrayList,LinkedList,Vector,Stack等类都实现了List接口,都属于List集合。
List接口里定义的基本方法是一样的。
public interface List
    extends Collection
{
    //... other Collection methods
   
    //根据索引取得元素
    public abstract Object get(int i);
    //在指定位置(索引)处插入新的元素
    public abstract Object set(int i, Object obj);
    //在List的尾部插入新的元素
    public abstract void add(int i, Object obj);
    //删除指定位置(索引)处的元素
    public abstract Object remove(int i);
    //取得指定对象的最开始的索引位置
    public abstract int indexOf(Object obj);
    //取得指定对象的最后的索引位置
    public abstract int lastIndexOf(Object obj);
    //List提供的新的遍历方法
    public abstract ListIterator listIterator();
    //从指定位置i处开始迭代。最初next()方法返回的将是位置i处的元素。
    public abstract ListIterator listIterator(int i);
    //取得从位置i到j的所有元素(包含i但不包含j位置的元素),返回一个新的集合对象。
    public abstract List subList(int i, int j);
}

 

ArrayList,LinkedList,Vector,Stack的相异之处:
数据构造上的差异:
ArrayList,Vector,Stack 都是使用动态数组来保存集合中的对象元素,亦即ArrayList,Vector,Stack具有基本相似的数据结构。ArrayList,Vector 除了以下所说的线程同步上的差异之外,它们的功能基本一样;Vector从Stack继承,除了拥有Stack具有的功能之外,还实现了栈的功能。
而LinkedList则使用链表的形式来保存集合中的对象元素。

线程处理上的差异:
ArrayList,LinkedList没有使用synchronized对线程同步作任何处理,也就是说它们在同一时刻可以由多个线程访问,不是线程安全的;
Vector,Stack则使用synchronized对主要方法作了同步控制,它们在同一时刻只能由一个线程访问。

 

ArrayList,LinkedList,Vector,Stack的性能比较:
因为数据构造上的差异,它们在处理元素的添加,删除,插入,索引取值,遍历取值方面的效率上也各不相同。
ArrayList,Vector,Stack都是采用动态数组,它们的处理效率基本一样。
LinkedList采用链表构造,所以它跟ArrayList,Vector,Stack在添加,删除,插入,取值操作上就很大差异。
在具体的应用中,为了性能,功能上的考虑,我们可以根据具体的需求采用不同的List。


ArrayList,Vector,Stack

元素添加操作
ArrayList,Vector,Stack添加元素时的基本步骤是:
- 确保动态数组的空间大小。若空间不够时,则为集合元素重新分配空间,新分配的空间是原有空间大小的1.5倍左右,并把原来的集合元素拷贝到新分配的空间上。所以如果对象元素很多,有可能分配的空间大小要远远多出实际的元素,所以为了内存利用效率考虑,使用ArrayList等时,如果事先知道元素的多少,最好初始化时为其分配最大空间。
- 设置新元素到size+1位置。
大量添加时的性能:因为重新分配空间的次数不会太多,性能评价:好
元素删除操作
- 将删除位置i以后的元素全部往前移一个位置
- 设置size处元素为null
大量删除时的性能:因为每个元素的删除都会进行移位拷贝,性能评价:差
元素插入操作
- 同 元素添加操作
- 将插入位置i及以后的所有元素往后移一个位置
- 设置新元素至插入位置i
大量插入时的性能:因为每个元素的插入都会进行移位拷贝,性能评价:差
索引取值/遍历取值
因为是动态数组结构,所以索引取值(根据数组的下标)的速度非常快。
它们的遍历取值(Iterator.next())的内部实现是根据当前元素的位置取得下一个元素,所以跟索引取值一样,都是简单地引用数组的下标,所以速度也非常快。
性能评价:极优


LinkedList

元素添加操作
元素删除操作
元素插入操作
LinkedList的元素添加,删除,插入的操作步骤一样:
- 定位需要操作的元素
- 执行添加,删除,插入操作
虽然在元素的定位操作上需要花些时间,但LinkedList在处理时对元素的定位作了优化,性能评价:好
索引取值
因为LinkedList的链表结构,所以对元素的索引取值是一个遍历的过程,性能评价:极差
遍历取值
LinkedList在遍历的时候保存了当前元素,因为它的链表结构,可以快速的定位下一个元素。性能评价:极优

性能总结:
     -      add()操作      delete()操作       insert操作         index取值操作      iterator取值操作   
ArrayList/Vector/Stack       好            差                差                    极优             极优   
LinkedList       好            好                好                    差               极优    

下面举例来说明它们在性能上的区别。



执行Client,输出结果:

C:/test/list>java com.test.collection.TestList ArrayList 100000
ArrayList  [add] : 79
ArrayList  [delete] : 8703
ArrayList  [insert] : 9281
ArrayList  [index] : 0
ArrayList  [iterator] : 16

C:/test/list>java com.test.collection.TestList LinkedList 100000
LinkedList  [add] : 125
LinkedList  [delete] : 16
LinkedList  [insert] : 78
LinkedList  [index] : 80328
LinkedList  [iterator] : 0

C:/test/list>java com.test.collection.TestList Vector 100000
Vector  [add] : 63
Vector  [delete] : 8546
Vector  [insert] : 9422
Vector  [index] : 16
Vector  [iterator] : 0

C:/test/list>java com.test.collection.TestList Stack 100000
Stack  [add] : 47
Stack  [delete] : 8593
Stack  [insert] : 9610
Stack  [index] : 0
Stack  [iterator] : 16


总结:
本文主要比较了ArrayList,Vector,Stack与LinkedList的操作性能。
ArrayList,Vector与Stack在索引取值,迭代取值上有较高的性能。
LinkedList在删除,插入,迭代取值上有较高的性能。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值