ArrayList源码分析
JDK7情况下
(一)空参构造器
ArrayList list=new ArrayList();
底层创建了长度为10的Object[]数组elementData。
StringBuffer和StringBuilder创建的是长度为16的char类型的数组value。
(二)添加数据
加之前先判断容量是否够,第一次添加size为0。
如果返回值是负数,就不会涉及扩容问题。
默认情况下,扩容为原来的1.5倍。StringBuffer扩容为2倍加2。如果扩容之后还不够,就直接扩容为加进来数据的长度,如果非常大就设置为Integer的最大值,再大就会报错OutOfMemoryError.
list.add(123);//elementData[0]=new Integer(123);
...
list.add(11);//如果此次的添加导致底层elementData数据容量不够,就扩容。默认情况下,扩容为原来的1.5倍,同时需要将原来的数组中的数据复制到新的数据中。
结论:建议开发中使用带参的构造器:
ArrayList list=new ArrayList(int capacity);
JDK8中ArrayList的变化
(一)空参构造器
一开始创建的数组为空,节省了内存。
ArrayList list= new ArrayList();//底层Object[] elementData初始化为{},并没有创建长度为10的数组。
(二)添加数据
第一次调用add()时才将数组创建好。
list.add(123);//第一次调用add()时,底层才创建长度为10的数组,并将数据123添加到elementData[0]
...
后续添加和扩容操作与jdk7无异。
结论
jdk7中的ArrayList的对象的创建类似于单例的饿汉式,提前创建好,而jdk8中的ArrayList的对象的创建类似于单例的懒汉式,延迟了数组的创建,节省内存。