JAVA數組深拷貝實現代碼

在使用org.apache.commons.lang.ArrayUtils進行數組拷貝的時候,發現其只能實現數組的淺拷貝,而且不支持泛型

經過改造,我自己重新實現了數組的深拷貝,同時支持多重數組拷貝。

因爲Object的clone方法聲明成protected,在使用泛型的時候,無法調用clone方法,所以我們自己重新定義個克隆的接口

package demo;

public interface MyCloneable {
    <T> T cloneObject();
}

再定義一個我們要使用的類,實現這個接口,實現對象的深拷貝

package demo;

import lombok.*;

@Getter
@Setter
@ToString
@RequiredArgsConstructor(staticName = "of")
public class MyObject implements MyCloneable{
    @NonNull
    String name;

    @Override
    public MyObject cloneObject() {
        //返回一個新的MyObject對象出來,相當於new MyObject()
        return MyObject.of(name);
    }
}

最後就是複製數組的代碼,在這裏使用泛型,以保證克隆前後數組類型不變

    public static <T> T[] cloneArray(T[] array) {
        if (array == null) {
            return null;
        }
        T[] newArr = array.clone();
        
        //找到數組中一個非空元素的下標
        int nonNullIndex = findNonNullIndex(newArr);
        if(nonNullIndex<0)
            return newArr;
        
        if(newArr[nonNullIndex].getClass().isArray()){  //如果元素是數組,那對每個元素進行數組拷貝
            if (newArr.length > 0) {
                for (int i = 0; i < newArr.length; i++) {
                    newArr[i] = (T) cloneArray((Object[]) newArr[i]);
                }
            }
        }else if(newArr[nonNullIndex] instanceof MyCloneable) { //如果元素實現了克隆接口,則對每個元素進行手動克隆,實現深克隆
            if (newArr.length > 0) {
                for (int i = 0; i < newArr.length; i++) {
                    if(newArr[i]!=null)
                        newArr[i] = ((MyCloneable)array[i]).cloneObject();
                }
            }
        }
        return newArr;
    }

    private static <T> int findNonNullIndex(T[] array){
        if(array==null)
            return -1;
        for(int i=0;i<array.length;i++){
            if(array[i]!=null)
                return i;
        }
        return -1;
    }

測試一下代碼

//ArrayUtils.clone()克隆數組,數組是新的,但是數組中的元素還是原來的對象
//重寫的clone可以進行深拷貝
MyObject[] myObjects = new MyObject[3];
myObjects[0] = MyObject.of("a");
MyObject[] myObjects1 = cloneArray(myObjects);
myObjects1[0].setName("1");
System.out.println();
Arrays.asList(myObjects).forEach(System.out::println);
Arrays.asList(myObjects1).forEach(System.out::println);

MyObject[][] myObjects2 = new MyObject[2][2];
myObjects2[0] = new MyObject[2];
myObjects2[0][1] = MyObject.of("01");
MyObject[][] myObjects3 = cloneArray(myObjects2);
myObjects3[0][1] = MyObject.of("aa");
System.out.println();
System.out.println(myObjects2[0][1]);
System.out.println(myObjects3[0][1]);

最後的結果

MyObject(name=a)
null
null
MyObject(name=1)
null
null

MyObject(name=01)
MyObject(name=aa)

 

發佈了22 篇原創文章 · 獲贊 2 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章