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

ArrayList动态扩容

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

ArrayList动态扩容

ArrayListJDK1.7源码内容
public class ArrayList extends AbstractList
        implements List, RandomAccess, Cloneable, java.io.Serializable
{
    private static final long serialVersionUID = 8683452581122892189L;

    
    private static final int DEFAULT_CAPACITY = 10;

    
    private static final Object[] EMPTY_ELEMENTDATA = {};

    
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    
    transient Object[] elementData; // non-private to simplify nested class access

    
    private int size;
    
    
    public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

从这些arraylist可以得知 ArrayList的的本质是一个数组,直接new出来的默认是个空数组

public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) {
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {
        this.elementData = EMPTY_ELEMENTDATA;
    } else {
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    }
}

从这个构造方法可以得知,ArrayList可以指定对应的大小

public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) {
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {
        this.elementData = EMPTY_ELEMENTDATA;
    } else {
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    }
}

这里源码可以知道ArrayList指定大小

public void trimToSize() {
    modCount++;
    if (size < elementData.length) {
        elementData = (size == 0)
          ? EMPTY_ELEMENTDATA
          : Arrays.copyOf(elementData, size);
    }
}

将ArrayList的实际容量调整为实际元素总个数大小,原是数组容量大小(内存优化方法)

ArrayList动态扩容

在外面数组的认知中,想要使用数组就一定要有指定固定大小,但是我们在使用ArrayList,发现是可以不用指定容器大小,随意添加对应内容不用关心容器大小,这是怎么实现的呢,今天我们从JDK源码中一探究竟。

首先咱们先来到add函数

public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

发现ensureCapacityInternal(size + 1);这个函数确保容器大小可以添加元素

private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

如果minCapacity大小大于原本的数组大小则执行grow(minCapacity)扩容函数

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    //oldCapacity >> 1  == oldCapacity /2  效率更高 
    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);
}

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

扩容函数中我们发现执行的顺序是获得当前数组size的1.5倍,所以我们知道了是扩容1.5倍,如果当前minCapacity大于1.5被的size直接用minCapacity为最新的size,如果newCapacity - MAX_ARRAY_SIZE > 0则用hugeCapacity(minCapacity)函数判断是Integer.MAX_VALUE当size还是Integer.MAX_VALUE - 8当size,可知道arraylist最大的大小为Integer.MAX_VALUE。

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

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

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