博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Jdk8集合源码解析---ArrayList
阅读量:6938 次
发布时间:2019-06-27

本文共 5846 字,大约阅读时间需要 19 分钟。

hot3.png

    ArrayList的数据结构

    ArrayList是一种线性数据结构,底层是动态数组实现的,与java中的数组相比,它的容量可以动态添加。

    ArrayList的类结构

public class ArrayList
extends AbstractList
implements List
, RandomAccess, Cloneable, java.io.Serializable{ ......}

    ArrayList的主要成员变量

//默认容量private static final int DEFAULT_CAPACITY = 10;private static final Object[] EMPTY_ELEMENTDATA = {};private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//ArrayList存储数据的数组transient Object[] elementData;//存储元素数目private int size;//默认最大容量数目private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;//protected transient int modCount = 0;

    ArrayList的构造方法

public ArrayList() {    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}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的主要方法

    存:

    boolean add(E e);

public boolean add(E e) {        //根据当前下角标size+1和当前数组的容量,判断是否需要扩容,如果需要,扩容到1.5倍        ensureCapacityInternal(size + 1);  // Increments modCount!!        //将新元素加入数组中,下角标为size+1        elementData[size++] = e;        return true;}private void ensureCapacityInternal(int minCapacity) {        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {            //如果存储元素的数组为空,容量值为10和minCapacity中的较大者            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);        }        ensureExplicitCapacity(minCapacity);}private void ensureExplicitCapacity(int minCapacity) {        //更新次数加一        modCount++;        // overflow-conscious code        if (minCapacity - elementData.length > 0)            //如果minCapacity大于当前数组的长度,扩容            grow(minCapacity);}private void grow(int minCapacity) {        //将当前数组的长度赋值给oldCapacity        int oldCapacity = elementData.length;        //新的容量值为原来的1.5倍        int newCapacity = oldCapacity + (oldCapacity >> 1);        if (newCapacity - minCapacity < 0)            //如果新容量值比minCapacity 值小,新容量值即为minCapacity            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            //如果minCapacity小于零,直接抛出OOM异常            throw new OutOfMemoryError();        //如果minCapacity大于最大数组容量,则返回Integer的最大值,否则返回        return (minCapacity > MAX_ARRAY_SIZE) ?            Integer.MAX_VALUE :            MAX_ARRAY_SIZE;}

    

    void add(int index,E e);

public void add(int index, E element) {        //校验下角标index是否越界        rangeCheckForAdd(index);        //判断是否需要扩容        ensureCapacityInternal(size + 1);  // Increments modCount!!        //将当前数组中下角标为[index,size]的元素复制到[index+1,size+1]的位置        System.arraycopy(elementData, index, elementData, index + 1,                         size - index);        //将element放置到数组下角标为index的位置        elementData[index] = element;        //数组内元素个数加1        size++;}private void rangeCheckForAdd(int index) {        if (index > size || index < 0)            //如果index大于数组元素的个数,或者index<0,抛出下角标越界异常            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}

    E  set(int index,E e);

public E set(int index, E element) {        //校验下角标是否越界        rangeCheck(index);        //将数组中下角标为index的元素赋值给oldValue        E oldValue = elementData(index);        //再将新元素放置到下角标index位置        elementData[index] = element;        //返回旧值        return oldValue;}

    取:

    E get(int index);

public E get(int index) {        //校验下角标是否越界        rangeCheck(index);        //返回数组中下角标为index的元素        return elementData(index);}private void rangeCheck(int index) {        if (index >= size)            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}

    

    移除:

    E remove(int index);通过下角标移除。

public E remove(int index) {        //判断下角标是否越界        rangeCheck(index);        //修改次数加一        modCount++;        //将数组中下角标为index的元素赋值给oldValue        E oldValue = elementData(index);        //要移动的元素个数        int numMoved = size - index - 1;        if (numMoved > 0)            //如果要移动的元素个数大于0,移动            // 将elementData数组index+1位置开始拷贝到elementData从index开始的空间             System.arraycopy(elementData, index+1, elementData, index,                             numMoved);        //最后一个元素设为null,并将size-1        elementData[--size] = null; // clear to let GC do its work        返回旧值        return oldValue;}

    boolean remove(Object o);移除指定元素

public boolean remove(Object o) {        if (o == null) {            //如果要移除的元素为null            //循环遍历数组            for (int index = 0; index < size; index++)                if (elementData[index] == null) {                    //如果某个下角标的元素为null                    //移除该下角标的元素                    fastRemove(index);                    return true;                }        } else {            //循环遍历数组            for (int index = 0; index < size; index++)                if (o.equals(elementData[index])) {                    //如果某个下角标的元素为o                    移除该下角标的元素                    fastRemove(index);                    return true;                }        }        return false;}private void fastRemove(int index) {        //修改次数加一        modCount++;        //要移动的元素个数        int numMoved = size - index - 1;        if (numMoved > 0)            // 将elementData数组index+1位置开始拷贝到elementData从index开始的空间             System.arraycopy(elementData, index+1, elementData, index,                             numMoved);        elementData[--size] = null; // clear to let GC do its work}

 

转载于:https://my.oschina.net/u/3765527/blog/1828334

你可能感兴趣的文章
hdu 2161(Primes)
查看>>
js 进阶 10 js选择器大全
查看>>
前端可编辑表格插件有哪些
查看>>
python学习day4之路
查看>>
Python 进阶_OOP 面向对象编程_静态方法和类方法
查看>>
Python 笔试集(2):你不知道的 Python 整数
查看>>
python学习笔记10(Python的内存管理)
查看>>
ES6系列_10之Symbol在对象中的作用
查看>>
EntityFramework获取数据库的时间
查看>>
getBoundingClientRect 获取某个元素信息
查看>>
Facebook 架构学习
查看>>
Java 多线程(三)—— 线程的生命周期及方法
查看>>
AngularJS学习总结
查看>>
MapReduce实现两表join
查看>>
怎么样去优化我们的SQL语句
查看>>
Java 代理模式(一) 静态代理
查看>>
应用缓存
查看>>
【二分答案】【最大流】bzoj1305 [CQOI2009]dance跳舞
查看>>
【AC自动机】【矩阵乘法】【等比数列】hdu2243 考研路茫茫——单词情结
查看>>
【动态规划】bzoj1270 [BeijingWc2008]雷涛的小猫
查看>>