list.add(list1)和list.add(new ArrayList<>(list1))

这是我在用回溯法写全排列的时候出现的问题,知识错误,特意对此进行巩固

首先,如果list的泛型是引用类型,那么list.add()添加的是地址,而不是值。所以,当你用一个对象(这里用list代替)来添加另一个对象(这里用list1代替),如果被添加的对象(list)值不断发生变化,那么在最后遍历list1的时候,最终的值会和list1的最后的相同
先附上一段小代码

public static void fun(){
        List<List<Integer>>  list= new ArrayList<>();
        List<Integer> list1= new ArrayList<>();
        for(int i = 1;i<=3;i++){
            list1.add(i);
            list.add(row);
        }
        //最终list的值会是[1,2,3],[1,2,3],[1,2,3]
        //这里只创建了两个对象,在最后一次将row集合加入到res中时,也将前面的值进行了赋值
        //list.add()加入的是指定对象的地址,当row的值进行变化时,row的内容也会发生变化

        for(int i = 1;i<=3;i++){
            list1.add(i);
            list.add(new ArrayList<>(list1));
        }
        //最终list的值会是[1],[1,2],[1,2,3]
        //这里是通过创建一个新的对象,将其加入到res集合中,并不会因为row的值发生变化而改变
    }

这段是我在写1,2,3的全排列的时候出现的问题代码,刚开始一直用list.add(list1),导致最终的list内容都为[],因为在代码中有list1.remove(list1.size()-1);最终list1的内容为[],最后经过查阅资料,改为list.add(new ArrayList<>(list1)).

import java.util.*;
public class Main {
	static List<List<Integer>> list = new ArrayList<>();
	
    public static void main(String[] args) {
        int[] nums = {1, 2, 3};
        List<Integer> list1 = new ArrayList<>();
        fun(nums, list1);
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
    }


    public static void fun(int[] nums, List<Integer> list1) {
        if (list1.size() == nums.length) {
            System.out.println(list1);
            list.add(new ArrayList<>(list1));
            //list.add(list1);错误
            //这里如果使用list.add(list1),最终会由于list1.remove(list.size()-1),list1的内容会变为0,从而使得list的内容也变为0
            return;
        }
        for (int i = 0; i < nums.length; i++) {
            if (list1.contains(nums[i])) {
                continue;
            }
            list1.add(nums[i]);
            fun(nums, list1);
            list1.remove(list1.size() - 1);
        }
    }
}

版权声明:本文为m0_48847163原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。