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)

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值