java中list集合的深度拷贝

编程人员经常误用各个集合类提供的拷贝构造函数作为克隆ListSetArrayListHashSet或者其他集合实现的方法。需要记住的是,Java集合的拷贝构造函数只提供浅拷贝而不是深拷贝,这意味着存储在原始List和克隆List中的对象是相同的,指向Java堆内存中相同的位置。增加了这个误解的原因之一是对于不可改变集合的浅克隆。由于不可变性,即使两个集合指向相同的对象是可以的。字符串池包含的字符串就是这种情况,更改一个不会影响到另一个。使用ArrayList的拷贝构造函数创建雇员List的拷贝时就会出现问题,Employee类不是不可变的。在这种情况下,如果原始集合修改了雇员信息,这个变化也将反映到克隆集合。同样如果克隆集合雇员信息发生变化,原始集合也会被更改。绝大多数情况下,这种变化不是我们所希望的,克隆对象应该与原始对象独立。解决这个问题的方法是深克隆集合,深克隆将递归克隆对象直到基本数据类型或者不可变类。本文将了解一下深拷贝ArrayList或者HashSet等集合类的一种方法。如果你了解深拷贝与浅拷贝之间的区别,那么理解集合深克隆的方法就会很简单。

Java集合的深克隆

下面有一个例子可以实现深度拷贝。

题目内容: Given a set of distinct integers, nums, return all possible subsets.


Note: The solution set must not contain duplicate subsets.


For example,
If nums = [1,2,3], a solution is:


[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]

j解决思路:只要我们能找到比原问题规模小却同质的问题,都可以用递归解决。比如要求{1, 2, 3}的所有子集,可以先求{2, 3}的所有子集,{2, 3}的子集同时也是{1, 2, 3} 的子集,
然后我们把{2, 3}的所有子集都加上元素1后(注意排序),又得到同样数量的子集, 它们也是{1, 2, 3}的子集。这样一来,我们就可以通过求{2, 3}的所有子集来求 
{1, 2, 3}的所有子集了。即为求1,2,3的子集,要先求2,3的子集,然后再把1加入到2,3的子集中去,典型的递归思路。

public static List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> list=new LinkedList<List<Integer>>();
if(nums.length<=0)return list;
List<Integer> l=new LinkedList<Integer>();
list.add(l);
int len=nums.length;
for(int i=0;i<len;i++){
list=to_next(list,nums,i);
}
return list;
}
 
private static List<List<Integer>> to_next(List<List<Integer>> list, int[] nums,
int k) {
// TODO Auto-generated method stub
int len=list.size();
for(int i=0;i<len;i++){
//深度拷贝,不然新建的list对象和原有对象指向相同引用对象
HashSet set=new HashSet(list.get(i));
set.add(nums[k]);
List<Integer> ll=new LinkedList<Integer>();
ll.addAll(set);
//sort
// Collections.sort(temp.get(i));
Collections.sort(ll);
list.add(ll);
}
return list;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值