栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

ArrayList 与Vector的扩容机制比较

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ArrayList 与Vector的扩容机制比较

最近开始背面试八股文,本着死记硬背不如真正理解的想法。我会记录一下自己对一些题目的理解(前提是自己能理解得了)

开始正题

首先是增方法均已add(E e)

先来看ArrayList的与增加有关的方法的源码

    

    public boolean add(E e) {
        //首先判断当前数组的大小是否能够达到size+1
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

     //判断数组大小的方法
    private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }

     //计算当前数组的大小  
 private static int calculateCapacity(Object[] elementData, int minCapacity) {
        
    //如果为数组为空,则返回指定大小与默认大小(默认为10)中大的那个  
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
     //否则返回当前大小
        return minCapacity;
    }
    //真正的判断&扩容数组的方法
    private void ensureExplicitCapacity(int minCapacity) {
        //将数组的修改次数+1 个人认为应该把这行放到grow()方法里
        modCount++;

        // overflow-conscious code
        //如果需求大小(在非空数组的情况下为当前size+1)大于数组长度时进行扩容
        if (minCapacity - elementData.length > 0)
            //扩容方法
            grow(minCapacity);
    }

    private void grow(int minCapacity) {
        // overflow-conscious code
        //存一下目前的长度
        int oldCapacity = elementData.length;
        //新的长度=目前的长度+位移一位的长度(0.5各oldCapcity)
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        //如果新的长度小于需求长度,则新的长度=需求长度
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        //如果新长度大于最大长度(Integer的MAX_VALUE-8),则将新长度设置为Inger的MAX_VALUE
        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);
    }


    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

再来看vector的

// synchronized  修饰,线程安全  
public synchronized void addElement(E obj) {
        modCount++; //修改次数+1
         //确保数组大小至少能够达到当前有效数量+1
        ensureCapacityHelper(elementCount + 1);
        
        elementData[elementCount++] = obj;
    }
    private void ensureCapacityHelper(int minCapacity) {
        // overflow-conscious code
        //如果大于数组长度则扩容
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

     //扩容机制与ArrayList大同小异
    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);
    }

    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

addAll()与add(int index,E e)的逻辑也大同小异,这里不做过多说明。

结论:

同:二者内部均为动态数组,且扩容逻辑大致相同。最终都是通过复制数组的形式来实现扩容

异:

每次扩容大小不同:

                                vector可以在构造函数中指定扩容大小,若不指定则每次扩容为原来的两倍。

                                arrayList无法指定扩容大小,每次扩容为原来的1.5倍

对线程安全的支持:

                                vetor的add方法有synchronized  关键字修饰,确保了线程安全

                                arrayList则没有,不保证线程安全

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/723933.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号