轉(zhuǎn)載自:http://qinheng053.blog.163.com/blog/static/873451120123921645688/
先看ArrayList源碼中數(shù)組復(fù)制的代碼:
其實(shí)ArrayList 就是一個(gè)數(shù)組的形式存放數(shù)據(jù)的. 沒有高深的地方.他的性能在于他的索引能力, 正因?yàn)樗菙?shù)組形式,所以索引元素的時(shí)候他表現(xiàn)得非常的快速成,所以查找的時(shí)候是非橙纾快的,但是插入或者刪除一條記錄就比較慢了匆背,試想一下, 只要知道這個(gè)元素的索引,E[2] 你看對像就出來了.這就是ArrayList 最突出的地方.
讓我們來看下ArrayList 內(nèi)部數(shù)組是如何自我Copy的.要想深入的了解他就必需要看他的API,add 方法與remove 方式.
看完后你就會(huì)對它有一個(gè)深刻的理解了.如下原碼:
Add 方法
public void add(int index, E element) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException( "Index: "+index+", Size: "+size);
ensureCapacity(size+1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1, size - index);
elementData[index] = element;
size++;
}
remove 方法
public E remove(int index) {
RangeCheck(index);
modCount++;
E oldValue = elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index, numMoved);
elementData[--size] = null; // Let gc do its work
return oldValue;
}
上述兩個(gè)方法足以讓你認(rèn)識(shí)他們了.他的主要執(zhí)行過程就在于數(shù)組對像的自我復(fù)制.System.arrayCopy. 這個(gè)方法是
System類中的一個(gè)JNI方式實(shí)現(xiàn)類.(JNI , Java Native Interface 故名思意,就是java 語言調(diào)其它語言的一個(gè)接口)
這個(gè)JNI的底層在不同的平臺(tái)上不一樣.打個(gè)比方windows 其實(shí)java的JNI就是調(diào)了dll . Unix 其實(shí)就是調(diào)了.so 共享庫. 做過C++的一定明白.這個(gè)暫且放一下,讓我們來關(guān)注一下arrayCopy 如何復(fù)制數(shù)組元素的. 如果有人對java 的JNI接口有興趣朋友,不防去Sun網(wǎng)站下它的源碼.嘎嘎. C代碼還是有點(diǎn)深度的.SCSL 源碼就能看到. 地址,
https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-Site/en_US/-/USD/ViewFilteredProducts-SingleVariationTypeFilter
(說明:要注冊一個(gè)SUN的賬號(hào).才可以下載.)
在JAVA里面,可以用復(fù)制語句"A=B"給基本類型的數(shù)據(jù)傳遞值,但是如果A,B是兩個(gè)同類型的數(shù)組,復(fù)制就相當(dāng)于將一個(gè)數(shù)組變量的引用傳遞給另一個(gè)數(shù)組;如果一個(gè)數(shù)組發(fā)生改變,那么引用同一數(shù)組的變量也要發(fā)生改變.
以下是歸納的JAVA中復(fù)制數(shù)組的方法:
1.使用FOR循環(huán),將數(shù)組的每個(gè)元素復(fù)制或者復(fù)制指定元素,不過效率差一點(diǎn)
2.使用clone方法,得到數(shù)組的值,而不是引用,不能復(fù)制指定元素,靈活性差一點(diǎn)
3.使用System.arraycopy(src, srcPos, dest, destPos, length)方法,推薦使用
舉例:
1.使用FOR循環(huán)
int[] src={1,3,5,6,7,8};
int[] dest = new int[6];
for(int i=0;i<6;i++) dest[i] = src[i];
2.使用clone
int[] src={1,3,5,6,7,8};
int[] dest;
dest=(int[]) src.clone();//使用clone創(chuàng)建
副本,注意clone要使用強(qiáng)制轉(zhuǎn)換
3.使用System.arraycopy
int[] src={1,3,5,6,7,8};
int[] dest = new int[6];
System.arraycopy(src, 0, dest, 0, 6);
-------------------------------------------------------------------
System提供了一個(gè)靜態(tài)方法arraycopy(),我們可以使用它來實(shí)現(xiàn)數(shù)組之間的復(fù)制.
其函數(shù)原型是:
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
src:源數(shù)組; srcPos:源數(shù)組要復(fù)制的起始位置;
dest:目的數(shù)組; destPos:目的數(shù)組放置的起始位置;
length:復(fù)制的長度.
注意:src and dest都必須是同類型或者可以進(jìn)行轉(zhuǎn)換類型的數(shù)組.
有趣的是這個(gè)函數(shù)可以實(shí)現(xiàn)自己到自己復(fù)制,
比如:int[] fun ={0,1,2,3,4,5,6};
System.arraycopy(fun,0,fun,3,3);
則結(jié)果為:{0,1,2,0,1,2,6};