/**
* (1)无参构造------>>当创建AraayList对象时,如果没有在小括号里面输入内容,则调用此(无参构造)方法
* 并且由于在有参构造时声明的是int 类型的initialCapacity(初识容量),小括号里只能填写int类型的内容
* public ArrayList() {\\ArrayList的无参构造
* this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
* }
* 注:elementData是一种Object类型的数组
* 注:DEFAULTCAPACITY_EMPTY_ELEMENTDATA的源码是==
* =>private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
* * 意思是,创建了一个Object类型的空的数组
* 注:this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;的意思就是===
* * => (this)这个(elementData)object类型的数组 ( =)等于(DEFAULTCAPACITY_EMPTY_ELEMENTDATA)空的数组
* *
* --------------------------------------------------------------------------------------------------------------------
*(2)带参构造方法------->>当创建AraayList对象时如果在小括号里输入了数字则调用此(带参构造)方法,没有则调用无参构造方法
* initialCapacity===初始容量 -->>初识容量就是当创建ArrayList对象时在小括号()里填的数字,如果不填则调用的是无参构造
* public ArrayList(int initialCapacity) {
* if (initialCapacity > 0) { \\如果初始容量(initialCapacity)大于0则--
*
* this.elementData = new Object[initialCapacity];--> elementData等于初识容量.
*
* } else if (initialCapacity == 0) { \\如果初识容量(initialCapacity)等于0则数组个数等于0
*
* this.elementData = EMPTY_ELEMENTDATA; -->elementData数组个数.
*
* //由于当初识容量出现负数时系统会报错出现异常,所以还需要编辑一个当初识容量既不是大于也不是大于0时的情况处理代码
*
* } else {//然后就出现了一下这一段代码----用于保证代码的健康性
*
* throw new IllegalArgumentException("Illegal Capacity: "+
* initialCapacity);
* }
* }
*/
//添加元素方法-----举例说明用的是调用无参构造的情况-->>elementsData=DEFAULTCAPACITY_EMPTY_ELEMENTDATA;已就是说数组个数为0
/*** (3)添加元素方法 add(Object obj)
* * public boolean add(E e) {||检测空间是否够用
* * ensureCapacityInternal(size + 1); // ensureCapacityInternal=>检测空间是否够用
* * elementData[size++] = e;
* * return true; //返回为true
* * }
*注://size是该数组集合(elementsData)当中的元素个数,因为调用的是无参构造,数组个数为0,则元素也为0,所以size=0
*注://size+1 => 0+1 => 得到的就是创建无参构造方法后得到的最小容量minCapacity
*注://添加元素 elementData[size]=e; size++; //size=>集合中元素个数
* (1)ensureCapacityInternal
* private void ensureCapacityInternal(int minCapacity) { //最小容量 创建对象时用的是默认初始数组长度为0
* ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); //calculateCapacity计算容量的
* }
* (1.0)calculateCapacity计算容量的方法
* private static int calculateCapacity (Object[] elementData, int minCapacity) {
* if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
* return Math.max(DEFAULT_CAPACITY, minCapacity);
* }
* return minCapacity;
* }
* 注://calculateCapacity方法有参(Object类型的数组,最小容量)//Object类型数组我们创建的是无参构造方法数组为空所以值为0
* 注://object类型的数组我们调用的是默认初始容量为{}所以Object[] elementData=0
* 注://DEFAULT_CAPACITY的中文意思为:默认容量
* 注://minCapacity=size+1;本次举例中调用的是无参构造方法elementsData(数组个数为o),所以元素个数size也为0
* 逻辑过程是:首先获得Object[] elementData(Object类型数组), int minCapacity(最小容量的值)进入程序
* 判断如果elementsData(数组个数)等于DEFAULTCAPACITY_EMPTY_ELEMENTDATA(空或者说等于0)返回为true进入if程序
* 返回 Math.max(这两个数当中的最大数)(DEFAULT_CAPACITY, minCapacity);
* 又因为本次举例中--->>DEFAULT_CAPACITY=10;minCapacity=1;所以返回10
* 如果if语句返回为false则
* 直接返回 minCapacity(最小容量)--->> 1
* (1.0.0)承接计算容量方法当中的DEFAULT_CAPACITY的源码:
* private static final int DEFAULT_CAPACITY = 10;//默认容量=10;
*所以计算之后calculateCapacity=10;带入到方法ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));当中后:
* =>ensureExplicitCapacity(10);
* (1.1)承接(1)当中的ensureExplicitCapacity方法:
* private void ensureExplicitCapacity(int minCapacity) {
*
* modCount++;
*
* if (minCapacity - elementData.length > 0)
* grow(minCapacity);
* }
* 注://由于(1.0)--计算容量的方法当中的计算结果等于10所以这里的minCapacity等于10;
* 注://elementData.length由于本次举例数组个数为0,所以elementData.length=0;
* 逻辑过程是:如果计算出来的的最小容量减去数组个数的长度大于0则
* 调用grow(扩充容量)方法并将minCapacity的值带入进去
* (1.1.1)承接(1.1)当中的grow(扩充容量)方法
* private void grow(int minCapacity) {//将minCapacity的值带入 //本次举例当中grow(minCapacity);==>>grow(10);
* int oldCapacity = elementData.length;//将数组长度(elementData.length)赋值给oldCapacity
* int newCapacity = oldCapacity + (oldCapacity >> 1);//oldCapacity + (oldCapacity >> 1)赋值给newCapacity等于0
* if (newCapacity - minCapacity < 0) //本次举例中 0-10<0 为true则
* newCapacity = minCapacity; //newCapacity(新的容量)=minCapacity(10);
* if (newCapacity - MAX_ARRAY_SIZE > 0)
* newCapacity = hugeCapacity(minCapacity);
* elementData = Arrays.copyOf(elementData, newCapacity);//elementData(数组个数)=10
* }
*
* 注://将oldCapacity + (oldCapacity >> 1)赋值给newCapacity ==> newCapacity=0+0; 所以newCapacity=0;
* 注://newCapacity = minCapacity;--新的容量(newCapacity)等于通过计算容量方法之后获得的最小容量(minCapacity)=10;
* 注://(oldCapacity >> 1)并不是默认为等于0,
* 而是因为是因为这是将oldCapacity的值等于0带入(oldCapacity >> 1)这个运算公式,运算后的结果才等于0
* 注://(oldCapacity >> 1)的值为多少有oldCapacity的值决定
* 注://>> 向右移位 例: 3>>1, 3向右移动一位,二进制表示为 11变为1,返回到十进制为 1。
* 注://MAX_ARRAY_SIZE 的定义:
* private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
* MAX_VALUE 的定义:
* public static final int MAX_VALUE = 0x7fffffff; 0x7FFFFFFF 对应 int.MaxValue 即2147483647
* 注://elementData = Arrays.copyOf(elementData, newCapacity);
*elementData(数组个数) = Arrays.copyOf(数组调用拷贝方法)(elementData(指定拷贝的值要赋予的对象), newCapacity(增加之后的新的容量))
* 上面小括号里的逻辑是:将newCapacity的值拷贝给elementsData
* 小括号里( ,)逗号后面的对象的值拷贝给( ,)逗号前面的对象
*/
public class TestAreeList {
/**ArrayList源码分析
* (1)无参构造方法
* this.elementData 是一个Object类型的数组
* DEFAULTCAPACITY_EMPTY_ELEMENTDATA;(this.elementData 的默认数组) 也是一个Object类型的数组
* DEFAULTCAPACITY_EMPTY_ELEMENTDATA={};默认长度为0
* public ArrayList() {
* this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
* //构造方法当中的这句代码相当于this.elementData={};----个人见解:默认数组为0的数组
* }
* (2)带参构造方法
* 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);
* }
* }
* (3)添加元素方法 add(Object obj)
* public boolean add(E e) {||检测空间是否够用
* ensureCapacityInternal(size + 1); // ensureCapacityInternal=>检测空间是否够用
* elementData[size++] = e;
* return true; //返回为true
* }
* (4)检测空间容量是否够用 ensureCapacityInternal
*
* private void ensureCapacityInternal(int minCapacity) { //最小容量 创建对象时用的是默认初始数组长度为0
* ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); //calculateCapacity计算容量的
* }
* 首先执行调用calculateCapacity 计算容量的方法
* private static int calculateCapacity (Object[] elementData, int minCapacity) {
* if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//true
* return Math.max(DEFAULT_CAPACITY, minCapacity);
* }
* return minCapacity;
* }//执行完返回为:10
* 容量计算完毕后执行ensureExplicitCapacity方法: //ensureExplicitCapacity(10)
* private void ensureExplicitCapacity(int minCapacity) {//10
*
* modCount++;
*
* if (minCapacity - elementData.length > 0)//10-0=10-->10>0 true
* grow(minCapacity);
* }
* (5)扩充容量的方法grow
*
* @param args
*/
public static void main(String[] args) {
//创建对象
List al=new ArrayList();
System.out.println(al.size());
//第一次调用添加方法时,完成的Objec类型的数组的初始化容量:10
al.add("hello");//添加的第一个元素
al.add("hello");//添加的第二个元素
/**
* //检测数组初始化容量,当添加第二个元素时:
*/
//检测数组初始化容量,当添加第二个元素:
// public boolean add(E e) {
// ensureCapacityInternal(size + 1); // 因为已经添加了一个元素所以size等于1; 1+1=2
// elementData[size++] = e;
// return true;
// }
// ---------------------------------------------------------------------------------
// private void ensureCapacityInternal(int minCapacity) {//minCapacity=2
// ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
// }
// --------------------------------------------------------------------------------
// private static int calculateCapacity(Object[] elementData, int minCapacity) {
// if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//因为已经添加了一个元素所以数组个数不为空所以if语句不执行
// return Math.max(DEFAULT_CAPACITY, minCapacity);
// }
// return minCapacity;//直接返回minCapacity=2;
// }
// -----------------------------------------------------------------------------------------------------------
// private void ensureExplicitCapacity(int minCapacity) {//minCapacity=2;
// modCount++;
//
// if (minCapacity - elementData.length > 0)//因为在添加第一个元素时已经完成了数组容量的初始化所以elementData.length=10;
// 2-10>0; 需要的最小容量减去初始化后的数组长度,小于0,所以不用扩充容量
// grow(minCapacity);返回为false所以if语句不执行
// }
// 以此类推可得初始化后的数组容量可以添加10个元素。
//以此类推可得初始化后的数组容量可以添加10个元素。
al.add("hello");
al.add("hello");
al.add("hello");
al.add("hello");
al.add("hello");
al.add("hello");
al.add("hello");
al.add("hello");//添加的第10个元素,添加完第10个元素之后要添加第11个元素时:
// public boolean add(E e) {//因为前面已经添加了10个元素所以size=10
// ensureCapacityInternal(size + 1); // 10+1=11;
// elementData[size++] = e;
// return true;
// }
// --------------------------------------------------------------------------------------------------------
// 计算容量
// private void ensureCapacityInternal(int minCapacity) {// minCapacity=11;
// ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
// }
// 首先调用执行calculateCapacity
// private static int calculateCapacity(Object[] elementData, int minCapacity) {//elementData=10, int minCapacity=11
// if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//false所以if语句不执行
// return Math.max(DEFAULT_CAPACITY, minCapacity);
// }
// return minCapacity;//直接返回 11 ;
// }
// 然后执行
// private void ensureExplicitCapacity(int minCapacity) {//minCapacity=11;
// modCount++;
//
// if (minCapacity - elementData.length > 0)//11-10>0 true
// grow(minCapacity);//执行grow方法
// }
// 执行grow方法
// private void grow(int minCapacity) {//minCapacity=11
// int oldCapacity = elementData.length; //将数组长度赋值给oldCapacity=10;
// int newCapacity = oldCapacity + (oldCapacity >> 1); //oldCapacity+(oldCapacity >> 1)的值赋给newCapacity=15
// if (newCapacity - minCapacity < 0)//newCapacity - minCapacity < 0 ==> 15-11<0 false
// newCapacity = minCapacity;
// if (newCapacity - MAX_ARRAY_SIZE > 0)
// newCapacity = hugeCapacity(minCapacity);
// elementData = Arrays.copyOf(elementData, newCapacity);//将newCapacity的值拷贝给elementData,得到数组个数为15;
// }
// 所以当添加第11个元素时又将进行一次扩容;扩容结果为15
//所以当添加第11个元素时又将进行一次扩容;扩容结果为15
al.add("hello");//添加的第11个元素
al.add("hello");//添加的第12个元素
}
}