ArrayList的add方法,浅拷贝

最近在写java全排列的题目时,

List<List<Integer>> result=new ArrayList();最终所有排列的集合
List<Integer> curlist=new ArrayList();动态的集合表示当前路径

最后出现了列表全空的bug,代码如下:

   void findpermution(int len,int[] nums,int layer,List<Integer> curlist, boolean[] used,List<List<Integer>> result){
        if(layer==nums.length){
            result.add(curlist);
            return;
        }
        for(int i=0;i<nums.length;i++)
        { 
            if(!used[i]){
                curlist.add(nums[i]);
                used[i]=true;
                findpermution(len,nums,layer+1,curlist,used,result);
                used[i]=false;
                curlist.remove(curlist.size()-1);
            }
        }
    }

搜索了一下才发现是 Arraylist.add(curlist) 这里的问题。Arraylist.add() 这个方法传递的是对象引用,每次的add只是将引用地址放入集合中,而没有创建新的对象(如果对于对象与对象引用有不明白的地方需要巩固下);从表面上来解释就是每一次想要添加的 list 都会覆盖原来的 list ,实际上是虽然对象在变,但引用不变,所以最终的运行结果是最后添加的对象变化(在全排列这题当中是最后回溯到path大小为0)。

解决方法:浅拷贝每次想要添加的list。

代码:

     if(layer==nums.length){
            result.add(new ArrayList<>(curlist));
            return;
        }

原理:相比较对象引用,浅拷贝构造了另一个引用。因此每次添加的都是当前改变的list。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值