java浅拷贝与深拷贝
java浅拷贝与深拷贝
java深拷贝
Java 中的数据类型分为基本数据类型和引用数据类型。对于这两种数据类型,在进行赋值操作、用作方法参数或返回值时,会有值传递和引用(地址)传递的差别。
- 针对于8大基本数据类型而言,浅拷贝相当于深拷贝,就是将原数据的值直接赋予新的对象
- 对于其他对象而言,浅拷贝就相当于复制一个引用,指向一块内存地址。
java浅拷贝
深拷贝,在拷贝引用类型成员变量时,为引用类型的数据成员另辟了一个独立的内存空间,实现真正内容上的拷贝。
- 深拷贝就相当于重新开辟一块内存。将原来的数值copy一份,然后再放置在这个内存区。
以Leetcode77题而言:
class Solution {
private List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> combine(int n, int k) {
dfs(n, k, 1, new ArrayList<>());
System.out.println(res);
return res;
}
public void dfs(int n, int k, int start, List<Integer> list) {
// 这里面k的定义是比较精髓的,k代表的是还能组合的位数,有了这个k,使得下面的for循环能够提前剪枝,真的是精妙
// 还要注意list作为形式参数传递的时候,传递的是一个引用,每次都是修改这个引用,就比如这里的list,虽然每次都向res中add一个list,但其实每一次add的时候都是
// add一个引用,下面修改list的时候,相当于把这个引用指向的内存区域也给改变了,所以会变成add一样的值
// 上面所述的传递一个引用就相当于一个浅拷贝
if(k == 0) {
// 这里要注意res.add与res.add(new ArrayList<>(list))之间的区别
// res.add(list);
res.add(new ArrayList<>(list));
System.out.println(list);
System.out.println("----------");
System.out.println(res);
return;
}
for(int i = start;i <= n-k+1;i++) {
// 这里改变了list指向的引用,而不是修改list本身的值
list.add(i);
dfs(n, k - 1, i+1, list);
// 这里就能改变也是list的引用,就会删除之后,就会导致最终res全部是[] 最终res = [[],[],[],[],[],[]]
list.remove(list.size() - 1);
}
}
}
如果使用add(list)方法的话:
如果使用add(new ArrayList
Saying Less Doing More