1. 程式人生 > >Java System.arraycopy

Java System.arraycopy

影響 arr 相同 src -- 指向 引用 復制 拷貝

System.arraycopy方法:如果是數組比較大,那麽使用System.arraycopy會比較有優勢,因為其使用的是內存復制,省去了大量的數組尋址訪問等時間

public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);

  復制指定源數組src到目標數組dest。復制從src的srcPos索引開始

,復制的個數是length,復制到dest的索引從destPos開始。

1.舉例

    @Test
    public void testCopy() {
        int[] ids = {1, 2, 3, 4, 5};

        // 1、測試復制到別的數組上
        // 將ids數組的索引從0開始其後5個數,復制到ids2數組的索引從0開始
        int[] ids2 = new int[5];
        System.arraycopy(ids, 0, ids2, 0, 5);
        System.out.println(Arrays.toString(ids2)); // [1, 2, 3, 4, 5]


        // 2、測試自我復制
        System.arraycopy(ids, 0, ids, 3, 2);
        System.out.println(Arrays.toString(ids)); // [1, 2, 3, 1, 2]


        // 3、如果是類型轉換問題
        Object[] o1 = {1, 2, 3, 4.5, 6.7};
        Integer[] o2 = new Integer[5];
        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]
    }

  

2、復制後改變復制後的數組

如果是復制一個一維數組,那麽改變復制後的數組並不影響原數組。但是如果復制一個二維數組,那麽改變其中任何一個數組,那麽另一個的值也發生了變化。開始不是很明白,後來上網查了查資料,理解了其中奧妙。

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

如果是一維數組,那麽元素都是基礎類型(如int,double等),使用arraycopy()方法後,是把原數組的值傳給了新數組,屬於值傳遞。而如果是二維數組,數組的第一維裝的是一個一維數組的引用,第二維裏是元素數值。對二維數組應用arraycopy()方法後,第一維的引用被復制給新數組的第一維,也就是兩個數組的第一維都指向相同的“那些數組”。而這時改變其中任何一個數組的元素的值,其實都修改了“那些數組”的元素的值,所以原數組和新數組的元素值都一樣了。

    @Test
    public void testCopy2(){
        int[] s1 = {1, 2, 3, 4, 5};
        int[] s2 = new int[5];
        System.arraycopy(s1, 0, s2, 0, 5);

        System.out.println("This is s1");
        for(int aS1 : s1) {
            System.out.print(aS1 + " , ");
        }

        s2[2] = 111;
        System.out.println("\nThis is s2");
        for(int aS2 : s2) {
            System.out.print(aS2 + " , ");
        }
        System.out.println("\nThis is s1");
        for(int aS1 : s1) {
            System.out.print(aS1 + " , ");
        }

        System.out.println("\n-----------------------");
        //二維數組
        int[][] s3 = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}};
        int[][] s4 = new int[s3.length][s3[0].length];
        System.out.println("This is s3");
        System.arraycopy(s3, 0, s4, 0, s3.length);
        for (int[] aS3 : s3) {
            for (int j = 0; j < s4[0].length; j++) {
                System.out.print(aS3[j] + ",");
            }
        }

        s4[1][3] = 111;
        System.out.println("\nThis is s4");
        for (int[] aS4 : s4) {
            for (int j = 0; j < s4[0].length; j++) {
                System.out.print(aS4[j] + ",");
            }
        }
        System.out.println("\nThis is s3");
        for (int[] aS3 : s3) {
            for (int j = 0; j < s4[0].length; j++) {
                System.out.print(aS3[j] + ",");
            }
        }
    }

  結果: This is s1 :1 , 2 , 3 , 4 , 5 ,
This is s2 : 1 , 2 , 111 , 4 , 5 ,
This is s1 : 1 , 2 , 3 , 4 , 5 ,
-----------------------
This is s3 : 1,2,3,4,5,6,7,8,9,10,
This is s4 : 1,2,3,4,5,6,7,8,111,10,

This is s3 : 1,2,3,4,5,6,7,8,111,10,

Java System.arraycopy