今天在刷lc时,又发现了个小问题。描述如下:
红色部分是最开始写的代码,得到满足sum==target的结果后,就将list加入到AllSets这个Arraylist中,一开始觉得没有什么问题,但是运行过后出现了下面的结果:
可以看到最终传入allSets中的竟然是两个空列表!这是为什么?
发现问题根源:可以看出,这个list 是由其他函数传入的参数,是一个引用类型,所以当我们只是单纯的进行allSets.add(list)时,只是把list的地址传递给了allSets,而list在深度优先搜索的最后,其实是一个空列表,因为每次添加元素后都会进行remove,所以最终加入到allSets的两个list最终其实都是空的,这也就是导致了以上的结果。这个相当于两个人复习,用同一份复习资料,其中有个人把资料撕掉了。
那么如何去解决?: 我们只需要将代码修改为allSets.add(new ArrayList<>(list));
即可,这样就相当于是创建了一个新的ArrayList对象,其内容是list 的值,等于我们创建了一个副本,就算原来的list怎么改变,也不会去改变副本的值。这个相当于两个人复习,用两份复习资料。总结:
- 当使用基本数据类型作为方法的形参时,在方法体中对形参的修改不会影响到实参的数值。
- 当使用引用数据类型作为方法的形参时,若在方法体中修改形参指向的数据内容,则会对实参变量的数值产生影响,因为形参变量和实参变量共享同一块堆区;在方法中对数组内容顺序进行交换,结果会影响实参。
- 当使用引用数据类型作为方法的形参时,若在方法体中修改形参变量的指向,此时不会 对实参变量的数值产生影响,因此形参变量和实参变量分别指向不同的堆区;在方法中将数组a指向数组b,不会影响实参。