Arraylist初始容量分配
知识体系重读,每天写一点,每天进步一点,对知识进行更深刻的理解,大神勿喷.
前言
为什么会研究这个简单的东西,在大家看来,以至于我看来Arraylist不就是用来存储数据的集合,是一个比数组更灵活,储存信息更多的一个API。
ArraylistAPI里的方法就那么一些,也很容易用,不会的只要查API也就很容易解决。
但是今天在重新查看API的时候,看到Arraylist的构造方法, 构造一个初始容量为 10 的空列表,这句话我记得当时在学习的时候也有简单的注意到但是现在却发现理解错了,简单分析如下。
正文
1.首先我是在想Arraylist和数组的区别,因为要给学生讲清楚,然后看到这一句话,我的第一反应是它和数组是一样的初始化10个固定的默认值
2.然后我就打印了一下Arraylist
ArrayList arrayList = new ArrayList();
System.out.println(arrayList.size());
结果是0,很意外
直接打印arraylist会打印一个空的数组,但是里面有没有分配初始值呢?
然后我查了一下,居然并不是想的那么简单。
引用块内容
ArrayList是经常会被用到的,一般情况下,使用的时候会像这样进行声明:
List arrayList = new ArrayList();
如果像上面这样使用默认的构造方法,初始容量被设置为10。当ArrayList中的元素超过10个以后,会重新分配内存空间,使数组的大小增长到16。
可以通过调试看到动态增长的数量变化:10->16->25->38->58->88->…
也可以使用下面的方式进行声明:
List arrayList = new ArrayList(4);
将ArrayList的默认容量设置为4。当ArrayList中的元素超过4个以后,会重新分配内存空间,使数组的大小增长到7。
可以通过调试看到动态增长的数量变化:4->7->11->17->26->…
那么容量变化的规则是什么呢?请看下面的公式:
((旧容量 * 3) / 2) + 1
注:这点与C#语言是不同的,C#当中的算法很简单,是翻倍。
一旦容量发生变化,就要带来额外的内存开销,和时间上的开销。
所以,在已经知道容量大小的情况下,推荐使用下面方式进行声明:
List arrayList = new ArrayList(CAPACITY_SIZE);
即指定默认容量大小的方式。
探索ArrayList自动改变size真相
ArrayList的列表对象实质上是存储在一个引用型数组里的,有人认为该数组有“自动增长机制”可以自动改变size大小。正式地说,该数组是无法改变
大小的,实际上它只是改变了该引用型数组的指向而已。下面,让我们来看看java是怎样实现ArrayList类的。
一、ArrayList类的实质
ArrayList底层采用Object类型的数组实现,当使用不带参数的构造方法生成ArrayList对象时,
实际上会在底层生成一个长度为10的Object类型数组。
首先,ArrayList定义了一个私有的未被序列化的数组elementData,用来存储ArrayList的对象列表(注意只定义未初始):
private transient Object[] elementData;
其次,以指定初始容量(Capacity)或把指定的Collection转换为引用型数组后实例化elementData数组;如果没有指定,则预置初始容量为10进行
实例化。把私有数组预先实例化,然后通过copyOf方法覆盖原数组,是实现自动改变ArrayList的大小(size)的关键。有人说ArrayList是复杂的数组,我
认为不如说ArrayList是关于数组的系统的方法组合。
ArrayList的构造方法源码如下:
// 用指定的初始容量构造一个空列表。
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException(“Illegal Capacity: “+initialCapacity);
this.elementData = new Object[initialCapacity];//属性指向新建长度为初始容量的临时数组
}
// 使用初始容量10构造一个空列表
public ArrayList() {
this(10);
}
/ *构造包含利用collection的迭代器按顺序返回的指定collection元素的列表
* @param c 集合,它的元素被用来放入列表t
* @throws NullPointerException 如果指定集合为 null
*/
public ArrayList(Collection