【java】陣列複製幾種方式比較
阿新 • • 發佈:2019-02-07
import java.util.Arrays; /** * System.arraycopy方法的使用。 * 從指定源陣列中複製一個數組,複製從指定的位置開始,到目標陣列的指定位置結束 藉助於一個臨時長度為length的陣列 */ public class LessionSystemArraycopy { public static void main(String[] args) { // 此方法為native方法。 也就是所非java語言實現的,靠近作業系統底層的語言寫的,供java程式去呼叫 // public static native void arraycopy( // Object src, int srcPos, Object dest, // int destPos, int length); // 初始化 int[] ids = { 1, 2, 3, 4, 5 }; System.out.println(Arrays.toString(ids)); // [1, 2, 3, 4, 5] // 把從索引0開始的2個數字複製到索引為3的位置上 System.arraycopy(ids, 0, ids, 3, 2); System.out.println(Arrays.toString(ids)); // [1, 2, 3, 1, 2] // 測試複製到別的陣列上 // 將資料的索引1開始的3個數據複製到目標的索引為0的位置上 int[] ids2 = new int[6]; System.arraycopy(ids, 1, ids2, 0, 3); System.out.println(Arrays.toString(ids2)); // [2, 3, 1, 0, 0, 0] // 此功能要求 // 源的起始位置+長度不能超過末尾 // 目標起始位置+長度不能超過末尾 // 且所有的引數不能為負數 try { System.arraycopy(ids, 0, ids2, 0, ids.length + 1); } catch (IndexOutOfBoundsException ex) { // 發生越界異常,資料不會改變 //ex.printStackTrace(); System.out.println("拷貝發生異常:資料越界。"); } System.out.println(Arrays.toString(ids2)); // [2, 3, 1, 0, 0, 0] // 如果是型別轉換問題 Object[] o1 = { 1, 2, 3, 4.5, 6.7 }; Integer[] o2 = new Integer[5]; System.out.println(Arrays.toString(o2)); // [null, null, null, null, null] try { System.arraycopy(o1, 0, o2, 0, o1.length); } catch (ArrayStoreException ex) { // 發生儲存轉換,部分成功的資料會被複制過去 System.out.println("拷貝發生異常:資料轉換錯誤,無法儲存。"); } // 從結果看,前面3個可以複製的資料已經被儲存了。剩下的則沒有 System.out.println(Arrays.toString(o2)); // [1, 2, 3, null, null] } }
JAVA語言的下面幾種陣列複製方法中,哪個效率最高? for迴圈逐一複製 System.arraycopy Arrays.copyof 使用clone方法 A、for迴圈的話,很靈活,但是程式碼不夠簡潔. B、System.arraycopy()原始碼。可以看到是native方法:native關鍵字說明其修飾的方法是一個原生態方法,方法對應的實現不是在當前檔案,而是在用其他語言(如C和C++)實現的檔案中。 可以將native方法比作Java程式同C程式的介面。 public static native void arraycopy(Object src, int srcPos, Object dest, int destPos,int length); native方法: Java不是完美的,Java的不足除了體現在執行速度上要比傳統的C++慢許多之外,Java無法直接訪問到作業系統底層(如系統硬體等),為此Java使用native方法來擴充套件Java程式的功能。 可以將native方法比作Java程式同C程式的介面,其實現步驟: 1、在Java中宣告native()方法,然後編譯; 2、用javah產生一個.h檔案; 3、寫一個.cpp檔案實現native匯出方法,其中需要包含第二步產生的.h檔案(注意其中又包含了JDK帶的jni.h檔案); 4、將第三步的.cpp檔案編譯成動態連結庫檔案; 5、在Java中用System.loadLibrary()方法載入第四步產生的動態連結庫檔案,這個native()方法就可以在Java中被訪問了。 C、選項有誤,copyOf不是System的方法,而是Arrays的方法, 下面是原始碼,可以看到本質上是呼叫的arraycopy方法。,那麼其效率必然是比不上arraycopy的 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;} D。clone的話,返回的是Object【】,需要強制轉換。 一般用clone效率是最差的 參考資料: http://blog.csdn.net/kesalin/article/details/566354 http://xuyuanshuaaa.iteye.com/blog/1046621 https://www.nowcoder.com/questionTerminal/915a9a1f5a3a4a6bbe5011c090bdf137
package Test; public class TestLoader { public static void main(String[] args) { String[] s1 = {"中國","山西","太原","TYUT","zyy","加拿大","不知道哪個州","不知道哪個市","不知道哪個學校","yxf"}; String[] s2 = new String[10]; System.arraycopy(s1, 0, s2, 0, 10); s2[6] = "假設蒙大拿州"; s2[7] = "假設蒙特利爾市"; s2[8] = "假設Montreal商學院"; System.out.println("This is s1"); for(int i = 0;i < s1.length ;i++){ System.out.print(s1[i] + ","); } System.out.println("\nThis is s2"); for(int i = 0;i < s2.length ;i++){ System.out.print(s2[i] + ","); } String[][] s3 = {{"中國","山西","太原","TYUT","zyy"},{"加拿大","不知道哪個州","不知道哪個市","不知道哪個學校","yxf"}}; String[][] s4 = new String[s3.length][s3[0].length]; System.arraycopy(s3, 0, s4, 0, s3.length); System.out.println("\nThis is original s3"); for(int i = 0;i < s3.length ;i++){ for(int j = 0; j< s3[0].length ;j++){ System.out.print(s3[i][j] + ","); } } s4[1][1] = "假設蒙大拿州"; s4[1][2] = "假設蒙特利爾市"; s4[1][3] = "假設Montreal商學院"; System.out.println("\nThis is s3 after s4 has changed."); for(int i = 0;i < s3.length ;i++){ for(int j = 0; j< s3[0].length ;j++){ System.out.print(s3[i][j] + ","); } } System.out.println("\nThis is s4"); for(int i = 0;i < s4.length ;i++){ for(int j = 0; j < s4[0].length ; j++){ System.out.print(s4[i][j] + ","); } } } } /* * 現象: * 如果是複製一個一位陣列,那麼改變複製後的陣列並不影響原陣列。 * 但是如果複製一個二維陣列,那麼改變其中任何一個數組,那麼另一個的值也發生了變化 * */ /* * 原因: * 如果是一維陣列,那麼元素都是基礎型別(如int,double等),使用arraycopy()方法後,是把原陣列的值傳給了新陣列,屬於值傳遞。 * 而如果是二維陣列,陣列的第一維裝的是一個一維陣列的引用,第二維裡是元素數值 * 對二維陣列應用arraycopy()方法後,第一維的引用被複制給新陣列的第一維,也就是兩個陣列的第一維都指向相同的“那些陣列”。 * 而這時改變其中任何一個數組的元素的值,其實都修改了“那些陣列”的元素的值,所以原陣列和新陣列的元素值都一樣了。 * */
package Test;
import java.util.Arrays;
public class HelloWorld{
public static void main(String[] args) {
int[] src = new int[1024 * 1024 * 100];
int[] dest = new int[1024 * 1024 * 100];
for (int i = 0; i < src.length; i++)
{src[i] = i;}
long startTime = System.currentTimeMillis();
for (int i = 0; i < src.length; i++) {
dest[i] = src[i];
}
long endTime = System.currentTimeMillis();
System.out.println("for : " + (endTime - startTime));
startTime = System.currentTimeMillis();
System.arraycopy(src, 0, dest, 0, src.length);
endTime = System.currentTimeMillis();
System.out.println("arraycopy : " + (endTime - startTime));
startTime = System.currentTimeMillis();
dest = Arrays.copyOf(src, src.length);
endTime = System.currentTimeMillis();
System.out.println("copyOf : " + (endTime - startTime));
startTime = System.currentTimeMillis();
dest = src.clone();
endTime = System.currentTimeMillis();
System.out.println("clone : " + (endTime - startTime));
}
}
/*
for : 86
arraycopy : 86
copyOf : 174
clone : 278
* for和arraycopy是差不多的
* copyof比clone快
* */