【潇湘菌子】从面试题学技术-ArrayList 和 Vector 的区别

ArrayList 和 Vector 的区别

  • 问题本质

Java集合的理解

  • 问题解释

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

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

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

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

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

  1. ArrayList

我们先来看看它的源码:

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

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

public class ArrayList<E> extends AbstractList<E> implements List<E>, 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;

}
 

 

  1. Vector

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

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

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

public class Vector<E> extends AbstractList<E> implements List<E>, 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)

 

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

 

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

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

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

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

static List<Object> arrayListSafe2 = Collections.synchronizedList(new ArrayList<Object>());  

 

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

 

  1. 其实和ArrayList以及Vector方法形式的类还有,hashmap ,hashtable 以及stringbuild,stringbuffer。后者都是前者的基础上增加了线程安全的实现。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

锁柱子

想白嫖?(笑)嫖就嫖吧(哈哈)

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值