【烟火气】从面试题学技术-ArrayList 和 Vector 的区别

ArrayList 和 Vector 的区别

一.问题本质

Java集合的理解

二.问题解释

首先,我们来看看集合的类图。


其中vector这个集合类现在已经很少用了,但是面试题中还可能遇到。我们的学习重点,应该几种在ArrayList,linkedlist,hashset和treeset上。

              接下来我们详细介绍一下ArrayList和vector,以后有机会再详细介绍其他接口。

              我么能看到,这俩接口都是继承自list的。所以我们可以对比着学。

              二者的实现大致相同,只是vector在ArrayList的基础上添加了线程安全关键字来约束。当执行synchronized修饰的方法前,系统会对该方法加一把锁,方法执行完成后释放锁。所以ArrayList的效率比较高,vector的安全性比较高。

1.  

我们先来看看它的源码:

首先,它是基于数组实现的(elementData),并且实现了list接口。

例如,下面的add和remove方法,我们可以使用他们来和vector来进行对比。

public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, Serializable {

transient Object[] elementData;

private int size;

}

private void add(E e, Object[] elementData, int s) {

if (s == elementData.length) {

        elementData =

this.grow();

    }

    elementData[s] = e;

this.size = s + 1;

}

public boolean add(E e) {

    ++

this.modCount;

this.add(e, this.elementData, this.size);

return true;

}

public E remove(int index) {

    Objects.checkIndex(index,

this.size);

    Object[] es =

this.elementData;

    E oldValue = es[index];

this.fastRemove(es, index);

return oldValue;

}

2.  Vector

我们首先看一下它的源码:

首先,它是基于数组实现的(elementData),并且实现了list接口,而且使用synchronized进行线程安全保证,这个可以在所有重要的方法中得到体现。

例如,下面的add和remove方法,可以看到,对外的接口使用synchronized进行修饰,保证线程安全。

public class Vector extends AbstractList implements List, RandomAccess, Cloneable, Serializable {

protected Object[] elementData;

protected int elementCount;

}

private void add(E e, Object[] elementData, int s) {

if (s == elementData.length) {

        elementData =

this.grow();

    }

    elementData[s] = e;

this.elementCount = s + 1;

}

public synchronized boolean add(E e) {

    ++

this.modCount;

this.add(e, this.elementData, this.elementCount);

return true;

}

public synchronized E remove(int index) {

    ++

this.modCount;

if (index >= this.elementCount) {

throw new ArrayIndexOutOfBoundsException(index);

    }

else {

        E oldValue =

this.elementData(index);

int numMoved = this.elementCount - index - 1;

if (numMoved > 0) {

            System.arraycopy(

this.elementData, index + 1, this.elementData, index, numMoved);

        }

this.elementData[--this.elementCount] = null;

return oldValue;

    }

}

三.区别

1.  Vector是线程安全的,ArrayList是线程不安全的(多了个synchronized)

2.   ArrayList在底层数组不够的时候,在原基础上扩充0.5倍,而vector扩充1倍。

四.延伸

1.  那么问题来了,为什么ArrayList线程不安全,怎么办?为什么大家不用vector呢?

原因大致有这么几个,因为线程安全,牺牲了效率;扩容的时候扩一倍,牺牲了空间;分配内存时容易失败;尾部增删,效率低。

2.  那么,如果用ArrayList又需要线程安全怎么办?

我们可以加上Collections.synchronizedList,它会自动将我们的list方法进行改变,最后返回给我们一个加锁了List

staticList arrayListSafe2 = Collections.synchronizedList(newArrayList()); 

那么,既然有ArrayList的线程安全同步方法,又有什么理由去使用vector呢?

3.   其实和ArrayList以及Vector方法形式的类还有,hashmap ,hashtable 以及stringbuild,stringbuffer。后者都是前者的基础上增加了线程安全的实现。

你可能感兴趣的:(【烟火气】从面试题学技术-ArrayList 和 Vector 的区别)