當(dāng)你停下來(lái)休息的時(shí)候,不要忘記,別人還在奔跑~
對(duì)上篇進(jìn)行一個(gè)補(bǔ)充。捧书。
1.ArrayList擴(kuò)容Demo
getCapacity()方法通過(guò)反射獲取ArrayList的容量苛吱。
public static Integer getCapacity(ArrayList list) {
Integer lenth = null;
Class c = list.getClass();
Field field;
try {
field = c.getDeclaredField("elementData");
field.setAccessible(true);
Object[] o = new Object[0];
try {
o = (Object[]) field.get(list);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
lenth = o.length;
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
return lenth;
}
第一次初始化ArrayList
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
Integer capacity = getCapacity(arrayList);
System.out.println("容量:"+capacity);
System.out.println("大欣沂酢:" +arrayList.size());
}
添加第一個(gè)元素的時(shí)候
public static void main(String[] args) {
ArrayList<String> arrayList2 = new ArrayList<>();
for (int i = 1; i <= 1; i++) {
arrayList2.add("value" + i);
}
Integer capacity = getCapacity(arrayList2);
System.out.println("容量:" + capacity);
System.out.println("大小:" + arrayList2.size());
}
將i改為9翠储,添加第9個(gè)元素
將i改為11绘雁,添加第11個(gè)元素
將i改為16,添加第16個(gè)元素
將i改為23援所,添加第23個(gè)元素
綜上:
當(dāng)數(shù)組中添加第一個(gè)元素時(shí)庐舟,數(shù)組容量擴(kuò)為10(默認(rèn)值DEFAULT_CAPACITY=10)。直到Size+1大于數(shù)組容量時(shí)住拭,就會(huì)去擴(kuò)容挪略,ArrayList 每次擴(kuò)容之后容量確實(shí)變?yōu)樵瓉?lái)的 1.5 倍左右(oldCapacity為偶數(shù)就是1.5倍,否則是1.5倍左右)滔岳! 奇偶不同杠娱,比如 :10+10/2 = 15, 15+15/2=22。如果是奇數(shù)的話會(huì)丟掉小數(shù)谱煤。
2.System.arraycopy() 和 Arrays.copyOf()方法
閱讀源碼的話摊求,我們就會(huì)發(fā)現(xiàn) ArrayList 中大量調(diào)用了這兩個(gè)方法。比如:我們上面講的擴(kuò)容操作以及add(int index, E element)刘离、toArray() 等方法中都用到了該方法室叉!
/**
* 在此列表中的指定位置插入指定的元素睹栖。
*先調(diào)用 rangeCheckForAdd 對(duì)index進(jìn)行界限檢查;然后調(diào)用 ensureCapacityInternal 方法保證capacity足夠大茧痕;
*再將從index開(kāi)始之后的所有成員后移一個(gè)位置野来;將element插入index位置;最后size加1踪旷。
*/
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
//arraycopy()方法實(shí)現(xiàn)數(shù)組自己復(fù)制自己
//elementData:源數(shù)組;index:源數(shù)組中的起始位置;elementData:目標(biāo)數(shù)組曼氛;index + 1:目標(biāo)數(shù)組中的起始位置; size - index:要復(fù)制的數(shù)組元素的數(shù)量埃脏;
System.arraycopy(elementData, index, elementData, index + 1, size - index);
elementData[index] = element;
size++;
}
/**
以正確的順序返回一個(gè)包含此列表中所有元素的數(shù)組(從第一個(gè)到最后一個(gè)元素); 返回的數(shù)組的運(yùn)行時(shí)類(lèi)型是指定數(shù)組的運(yùn)行時(shí)類(lèi)型搪锣。
*/
public Object[] toArray() {
//elementData:要復(fù)制的數(shù)組;size:要復(fù)制的長(zhǎng)度
return Arrays.copyOf(elementData, size);
}
聯(lián)系:
看兩者源代碼可以發(fā)現(xiàn) copyOf() 內(nèi)部實(shí)際調(diào)用了 System.arraycopy() 方法區(qū)別:
arraycopy() 需要目標(biāo)數(shù)組彩掐,將原數(shù)組拷貝到你自己定義的數(shù)組里或者原數(shù)組,而且可以選擇拷貝的起點(diǎn)和長(zhǎng)度以及放入新數(shù)組中的位置 copyOf() 是系統(tǒng)自動(dòng)在內(nèi)部新建一個(gè)數(shù)組灰追,并返回該數(shù)組堵幽。
3.基本常識(shí):
java 中的 length 屬性是針對(duì)數(shù)組說(shuō)的,比如說(shuō)你聲明了一個(gè)數(shù)組,想知道這個(gè)數(shù)組的長(zhǎng)度則用到了 length 這個(gè)屬性.
java 中的 length() 方法是針對(duì)字符串說(shuō)的,如果想看這個(gè)字符串的長(zhǎng)度則用到 length() 這個(gè)方法.
java 中的 size() 方法是針對(duì)泛型集合說(shuō)的,如果想看這個(gè)泛型有多少個(gè)元素,就調(diào)用此方法來(lái)查看!