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

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

源自:jdk1.8.0_121

ArrayList继承自AbstractList,实现了ListRandomAccessCloneableSerializable

ArrayList内部是通过数组及数组的扩容来实现

变量

// 默认容量为10    private static final int DEFAULT_CAPACITY = 10;    // 空数组    private static final Object[] EMPTY_ELEMENTDATA = {};    // 默认空数组    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};    // 存放数据的数组,被transient修饰的参数不会被序列化    transient Object[] elementData;    // 实际元素的大小    private int size;

构造方法

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);        }    }    public ArrayList() {        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;    }    public ArrayList(Collection
c) { elementData = c.toArray(); if ((size = elementData.length) != 0) { // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } else { // replace with empty array. this.elementData = EMPTY_ELEMENTDATA; } }

toArray()实现方式的不同

注:ArrayList(Collection<? extends E> c) 之所以要判断是否为Object类型,是因为调用toArray()方法的实现方式不同。

java.util.ArrayList中,toArray()返回的是Object数组。

public Object[] toArray() {        return Arrays.copyOf(elementData, size);    }

java.util.Arrays中,有个名为ArrayList的内部类,当调用Arrays.asList()时,返回的是java.util.Arrays$ArrayList内部类对象,而并非java.util.ArrayListjava.util.Arrays$ArrayList中的toArray()返回的虽然是Object数组,但它是有真是类型的数组。

private final E[] a;    public Object[] toArray() {        return a.clone();    }

ArrayList扩容

public boolean add(E e) {        ensureCapacityInternal(size + 1);  // Increments modCount!!        elementData[size++] = e;        return true;    }    private void ensureCapacityInternal(int minCapacity) {        if (elementData == DEFAULTCAPACITY_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);    }

从源码可以看出,如果1.5倍的elementData.length小于10,会将elementData的大小扩容成默认的10,反之,则会以1.5倍的elementData.length进行扩容。

将elementData设置为实际容量,动态扩充的多余容量将被删除

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

转载于:https://www.cnblogs.com/jarjune/p/8341003.html

你可能感兴趣的文章
【基础练习】【区间DP】codevs1090 加分二叉树题解
查看>>
HTML5:web socket 和 web worker
查看>>
[转载]从零开始学习OpenGL ES之五 – 材质
查看>>
mobiscroll手机端插件 好用(时间、日历、颜色)
查看>>
利用vertical-align:middle实现在整个页面居中
查看>>
★★停止动画和停止所有动画$(selector).stop() 详解
查看>>
160429、nodejs--Socket.IO即时通讯
查看>>
Poj2826 An Easy Problem
查看>>
ZipUtils
查看>>
浏览器最大连接数
查看>>
memcached系列之二
查看>>
about mobile web
查看>>
ajax 的post方法用例(带循环)
查看>>
009_【OS X和iOS系统学习笔记】 OS X架构
查看>>
中止法
查看>>
Android mainfests手记
查看>>
列表的方法
查看>>
锋利的jQuery--读书笔记
查看>>
herbetr遇到 Cannot cast java.lang.Character to java.lang.Stringat java.lang.Class.cast
查看>>
Surface电池阈值
查看>>