關於System.arrayCopy()方法

java其實沒有二維數組的概念,日常實現的二維數組只是元素是一維數組的一維數組,而數組也是引用類型,繼承自Object類。數組是new出來的。這些性質也就致使arraycopy()二維數組時出現的問題。java

一、首先對於一維數組,若是元素都是基礎類型(如int,double等),使用arraycopy()方法後,是把原數組的值傳給了新數組,屬於值傳遞,故修改複製後的數組,原數組不受到影響。若是是不可變類如String,雖然屬於引用傳遞,可是具備不可變的特徵,故修改複製後的數組,原數組不受到影響。 二、對於二維數組,數組的第一維裝的是一個一維數組的引用,第二維裏是元素數值。對二維數組應用arraycopy()方法後,第一維的引用被複制給新數組的第一維,也就是兩個數組的第一維都指向相同的「那些數組」。而這時改變其中任何一個數組的元素的值,其實都修改了「那些數組」的元素的值,因此原數組和新數組的元素值都同樣了。數組

System.arraycopy()的實現方法: 首先查看System.arraycopy()的API public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)將指定源數組中的數組從指定位置複製到目標數組的指定位置。 陣列組件的一個子序列被從經過引用的源陣列複製src被引用的目標陣列dest 。 複製的組件數量等於length參數。 源陣列中位置srcPos至srcPos+length-1的組件分別複製到目標陣列的位置destPos至destPos+length-1 。 若是src個dest參數指代相同的數組對象,則被處理是否在位置上的部件進行復印srcPos經過srcPos+length-1首先被複制到一個臨時的陣列length組分,而後將臨時數組的內容被複制到的位置destPos經過destPos+length-1目標數組的。操作系統

其中 Arrays.copy是JDK1.6中引用的新方法。它調用了System.arraycopy完成相關數組的複製。 在JDK1.6中ArrayList的相關add remove等操做都是調用System.arraycopy來對其底層的Object[]elementData數組進行操做的。 LinkedList則使用一個Entry的內部類,其有指向next和previous的引用保存元素,它的遍歷則先計算出所需index和size>>1(覺得後的大小),肯定是經過previous仍是next遍歷。 查看System.arraycopy() 的源碼: public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length); 能夠看到它是native方法,通常是藉助C/C++實現的,Java沒法直接訪問到操做系統底層(如系統硬件等),爲此Java使用native方法來擴展Java程序的功能。對象

  能夠將native方法比做Java程序同C程序的接口,其實現步驟:繼承

  1、在Java中聲明native()方法,而後編譯;遞歸

  2、用javah產生一個.h文件;接口

  3、寫一個.cpp文件實現native導出方法,其中須要包含第二步產生的.h文件(注意其中又包含了JDK帶的jni.h文件);內存

  4、將第三步的.cpp文件編譯成動態連接庫文件;element

  5、在Java中用System.loadLibrary()方法加載第四步產生的動態連接庫文件,這個native()方法就能夠在Java中被訪問了。rem

最後關於幾種數組複製的效率問題: 一、for循環,手動複製 二、System.arraycopy()方法 三、Arrays.copyOf()方法 四、clone()方法 結論: 因爲System.arraycopy()是最貼近底層的,其使用的是內存複製,省去了大量的數組尋址訪問等時間,故效率最高。 對於Arrays.copyOf()方法查看源碼能夠看到: public static int[] copyOf(int[] original, int newLength) { int[] copy = new int[newLength]; System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy; } 它是藉助System.arraycopy()方法實現的,故效率次於System.arraycopy() clone()方法效率是最低的,通常須要重寫,clone的方法Object執行特定的克隆操做。 首先,若是此對象的類不實現接口Cloneable ,則拋出CloneNotSupportedException 。 請注意,全部數組都被認爲是實現接口Cloneable ,而且數組類型T[]的clone方法的返回類型是T[] ,其中T是任何引用或原始類型。 不然,該方法將建立該對象的類的新實例,並將其全部字段初始化爲徹底符合該對象的相應字段的內容,就像經過賦值同樣。 這些字段的內容自己不被克隆。 所以,該方法執行該對象的「淺拷貝」,而不是「深度拷貝」操做。若是須要「深度拷貝」操做,則須要遞歸clone() 對於數組空間小的狀況下,前三種差異不大,對於比較大的數組,即可以明顯看出差異。

相關文章
相關標籤/搜索