关于ArrayList和Vector空间利用率的一点探索

本文深入探讨了ArrayList和Vector两种容器的底层实现原理,特别是它们在容量扩展机制上的差异。通过对源码的分析,揭示了Vector在容量增长时比ArrayList更激进,但这并不意味着Vector的空间利用率总是优于ArrayList。
摘要由CSDN通过智能技术生成

原文链接:https://blog.csdn.net/Javanjg/article/details/53025786
看到一篇java方面的文章其中提到ArrayList和Vector俩容器,文章作者提到Vector的空间利用率比ArrayList要大,最有意思的是他说Vector的空间利用率能达到100%。看到这里我就醉了,想着基于java数组实现的Vector容器利用率能达到100%,要想达到每次增加一个元素,利用率能达到100%,岂不是每次Vector容量的扩增只能是1,否则怎么可能每次扩增利用率能达到100%。想到这里,于是我查看了下ArrayList和Vector的源码。

关于Vector底层数组容量扩增的源码:


public synchronized boolean add(E e) {
    modCount++;
    ensureCapacityHelper(elementCount + 1);
    elementData[elementCount++] = e;
    return true;
}
private void ensureCapacityHelper(int minCapacity) {
    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}
private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                     capacityIncrement : oldCapacity);//扩容
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    elementData = Arrays.copyOf(elementData, newCapacity);
}

从上可以轻易的看出如果没有指定初始增加容量capacityIncrement的值,那它为默认值0。
int newCapacity=oldCapacity+oldCapacity。在原有的基础上扩增一倍。查看源码可知Vector的初始容量为10,如果存储11个数那他的空间利用率为f = 11/(10*2)=55%、存储20个数f = 20/(10*2)=100%。

同理,下面我们来看下ArrayList的容量扩展代码:


public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}
private void ensureCapacityInternal(int minCapacity) {
    if (elementData == EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }
 
    ensureExplicitCapacity(minCapacity);
}
 
private void ensureExplicitCapacity(int minCapacity) {
    modCount++;
 
    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}
private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);//扩增容量
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);
}

从上可以得知newCapacity = oldCapacity+oldCapacity/2;也就是说如果容量需要扩增时每次只能扩增他当前容量的50%。而Vector是扩增100%。所以我们来看看它的容量利用率。查源码得知ArrayList的初始容量也是10。假如存储11个数到ArrayList那利用率f = 11/(10+10*50%)=73.3%,如果是增加20则利用率为f=20/(15+15*50%)=90%,刚好增加10个那肯定是100%。
由上数据分析可知:ArrayList和Vector的空间利用率其实是没有比较的意义的。不存在说Vector的空间利用率比ArrayList大,更不可能说Vector的空间利用率是100%,只能说有时它能达到100%。但查看源码得知,不管是ArrayList还是Vector他们都可以在初始化的时候指定对应的初始增加容量,所以当我们知道需要存储的数据是多少时,我们可以自己指定需要增加的容量,一步到位。不需要让其自身去增加,降低性能。

Vector和ArrayList的区别是ArrayList它每次是增加自身50%的容量而Vector是增加100%,所以当我们处理的数据量较大时使用Vector存储效率更高因为他容量扩增的次数比ArrayList要少。所以很多书上说Vector是大容量容器而List接口下的实现类则是小容量容器这是有一定的道理的。而且Vector是支持线程同步的,所以多线程并发访问时Vector是安全的,但是ArrayList则不支持线程同步,需要人为的去定义才能使ArrayList支持线程同步。从这点上看,Vector确实比ArrayList有优势,但是有利也有弊。这样一来就降低了Vector的效率。所以在开发过程中需要找他它俩者的平衡点再选择使用哪个容器则是最好的。谁都不比谁优劣。
--------------------- 
作者:爱吃小丸子s 
来源:CSDN 
原文:https://blog.csdn.net/javanjg/article/details/53025786 
版权声明:本文为博主原创文章,转载请附上博文链接!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值