对ArrayList、Vector和LinkedList的理解

做java开发也有一年多了,对于数组、集合的使用也不少,今天抽出时间把它们系统的梳理一下,整理出以下内容:

首先让我们来看Collection FrameWork:


Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements)

一、ArrayList(动态数组),Vector(对象数组), LinkedList(链表)的存储性能和特性

1、ArrayList使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢

2、Vector同样也是使用了数组方式存储数据,但是由于使用了synchronized方法(线程安全),通常性能上较ArrayList要差

3、LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。

二、ArrayList和Vector同样都是使用数组方式存储数据,那么它们有区别吗

ArrayList和Vector的区别主要体现在以下两个方面

1、同步性:Vector是线程安全的,是线程同步的,而ArrayList是线程序不安全的,线程不同步的。如果只有一个线程会访问到集

合,最好使用ArrayList,因为它不考虑线程安全,效率会高些;如果有多个线程访问集合,最好使用Vector。

2、数据增长:ArrayList与Vector都有一个初始的容量大小,当存储进它们里面的元素的个数超过了容量时,就需要增加ArrayList

与Vector的存储空间,每次要增加存储空间时,不是只增加一个存储单元,而是增加多个存储单元,每次增加的存储单元的个数在

内存空间利用与程序效率之间要取得一定的平衡。Vector默认增长为原来两倍,而ArrayList的增长策略在文档中没有明确规定(从

源代码看到的是增长为原来的1.5倍)。ArrayList与Vector都可以设置初始的空间大小,Vector还可以设置增长的空间大小,而

ArrayList没有提供设置增长空间的方法。可见:即Vector增长原来的一倍,ArrayList增加原来的0.5倍。

三、ArrayList的大小是如何自动增加的

事实上,当有人试图在ArrayList中增加一个对象的时候,Java会去检查ArrayList,以确保已存在的数组中有足够的容量来存储

这个新的对象。如果没有足够容量的话,那么就会新建一个长度更长的数组,旧的数组就会使用Arrays.copyOf方法被复制到新的数

组中去,现有的数组引用指向了新的数组。代码如下:

//ArrayList Add方法:

public boolean add(E e){

    ensureCapacity(size+1); //Increment modCount!!

    elementData[size++] = e;

    return true;

}

 

//ensureCapacity方法:处理ArrayList的大小

public void ensureCapacity(int minCapacity) {

    modCount++;

    int oldCapacity = elementData.length;

    if (minCapacity > oldCapacity) {

    Object oldData[] = elementData;

    int newCapacity = (oldCapacity * 3)/2 + 1;

    if (newCapacity < minCapacity)

        newCapacity = minCapacity;

    // minCapacity is usually close to size, so this is a win:

    elementData = Arrays.copyOf(elementData, newCapacity);

    }

}

四、什么时候使用ArrayList,什么时候使用LinkedList

根据ArrayList和LinkedList的存储性能和特性,多数情况下,当遇到访问元素比插入或者是删除元素更加频繁的时候,应该使

用ArrayList。另一方面,当在某个特别的索引中,插入或者是删除元素更加频繁,或者压根就不需要访问元素的时候,此时应选择

LinkedList。这里的主要原因为,在ArrayList中访问元素的最糟糕的时间复杂度是“1″,而在LinkedList中可能就是“n”了。在ArrayList中增加或者删除某个元素,通常会调用System.arraycopy方法,这是一种极为消耗资源的操作,因此,在频繁的插入或者是删除元素的情况下,LinkedList的性能会更加好,效率更高。

五、当传递ArrayList到方法中,或者方法返回ArrayList,什么时候需要考虑安全问题呢?如何避免?

当array被当做参数传递到某个方法中,如果array在没有被复制的情况下直接被分配给了成员变量,那么就可能发生这种

况,即当原始的数组被调用的方法改变的时候,传递到这个方法中的数组也会改变。


ArrayList被直接赋给成员变量时,有安全隐患:

public void setMyArray(String[] myArray) {

this.myArray = myArray;

}

如何避免:

public void setMyArray(String[] newMyArray) {

if(newMyArray == null) {

this.myArray = new String[0];

} else {

this.myArray = Arrays.copyOf(newMyArray ,newMyArray .length);

}

}

六、如何复制某个ArrayList到另一个ArrayList中去

以下是把某个ArrayList复制到另一个ArrayList中去的几种技术:

1、使用clone()方法,例:ArrayList newArray = oldArray.clone();


2、使用ArrayList构造方法,

例:ArrayList myObject = new ArrayList(myTempObject);


3、使用Collection的copy方法

七、在ArrayList中增加或者删除元素时效率怎样

在ArrayList中增加或者是删除元素时,需要调用System.arraycopy这种效率很低的操作,所以效率很低。









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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值