如何实现ArrayList<E>泛型的复制

本文详细介绍了如何在类ImmutableQueue中获取私有变量iQueue的深复制副本,以实现对内容的访问而不修改原始变量。通过序列化技术实现深复制,确保了复制对象之间的独立性和安全性。

       问题解释:

       现在一个类ImmutableQueue里有一个私有变量iQueue,这是一个ArrayList<E>泛型变量。我现在要得到他的一个副本,以便对这个私有变量的内容进行访问,并且不修改iQueue的内容。

解决:

       首先说System.arraycopy(),直接写System.arraycopy(iQueue,0,CopyQueue,0,size),会报错: 

        ArrayStoreException。似乎是因为arraycopy不支持泛型。

       用Addall倒是不会报错,奇怪的是Addall其实是System.arraycopy()实现的,不太清楚为什么。但是无论是addall还是arraycopy(),都是浅复制,如果对CopyQueue,可能会影响到原来变量的内容。

下面回顾一下深复制和浅复制。

        比如一个类:      

</pre><pre name="code" class="java">class A
{
    int value;
    B b
}

class B
{
    char key;
}


               a中有另一个类b的对象的引用,那么对A的一个对象a1的浅复制a2,他们的b都指向同一个B的对象。如果是深复制,则他们的b指向不同的B对象。clone是浅复制,arraycopy也是浅复制。深复制使用序列化来完成,这里借鉴下别人的代码: 首先要在原来的类后面加implements Serializable:  

        然后写deepcopy的函数:

public ArrayList<E> getQueueCopy() throws Exception
	{  
		ByteArrayOutputStream byteOut = new ByteArrayOutputStream();  
		ObjectOutputStream out = new ObjectOutputStream(byteOut);  
		out.writeObject(iQueue);  
		  
		ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());  
		ObjectInputStream in = new ObjectInputStream(byteIn);  		  
		@SuppressWarnings("unchecked")
		ArrayList<E> CopyQueue = (ArrayList<E>) in.readObject();  
		return CopyQueue;   
	}

        但是要求你的E也是实现了序列化的类。不然似乎也不行……希望以后能找到比较好的方法。

/** * 快照类:保存排程状态副本 */ public static class ScheduleSnapshot { private final Map<String, Map<Date, BigDecimal>> remainingTimeMap; private final Set<String> filledClasses; private final Map<String, Set<String>> filledClasses2; private final Map<String, Set<String>> deviceOccupyMap; private final Map<String, List<PpMachiningOrderList>> assignedCache; private final Map<String, Map<Date, List<String>>> tem; public ScheduleSnapshot( Map<String, Map<Date, BigDecimal>> remainingTimeMap, Set<String> filledClasses, Map<String, Set<String>> filledClasses2, Map<String, Set<String>> deviceOccupyMap, Map<String, List<PpMachiningOrderList>> assignedCache, Map<String, Map<Date, List<String>>> tem) { this.remainingTimeMap = deepCopyRemainingTimeMap(remainingTimeMap); this.filledClasses = new HashSet<>(filledClasses); this.filledClasses2 = deepCopyFilledClasses2(filledClasses2); this.deviceOccupyMap = deepCopyFilledClasses2(deviceOccupyMap); this.assignedCache = deepCopyAssignedCache(assignedCache); this.tem = deepCopyTem(tem); } private Map<String, Map<Date, BigDecimal>> deepCopyRemainingTimeMap(Map<String, Map<Date, BigDecimal>> src) { return src.entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, e -> new HashMap<>(e.getValue()))); } private Map<String, Set<String>> deepCopyFilledClasses2(Map<String, Set<String>> src) { return src.entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, e -> new HashSet<>(e.getValue()))); } private Map<String, Map<Date, List<String>>> deepCopyTem(Map<String, Map<Date, List<String>>> src) { return src.entrySet().stream() .collect(Collectors.toMap( Map.Entry::getKey, e -> e.getValue().entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, innerE -> new ArrayList<>(innerE.getValue()))) )); } private Map<String, List<PpMachiningOrderList>> deepCopyAssignedCache(Map<String, List<PpMachiningOrderList>> src) { return src.entrySet().stream() .collect(Collectors.toMap( Map.Entry::getKey, e -> new ArrayList<>(e.getValue()) // 浅拷贝:新建 list,但对象引用相同 )); } /** * 恢复所有状态 */ public void restore( Map<String, Map<Date, BigDecimal>> remainingTimeMap, Set<String> filledClasses, Map<String, Set<String>> filledClasses2, Map<String, Map<Date, List<String>>> tem, Map<String, Set<String>> deviceOccupyMap, Map<String, List<PpMachiningOrderList>> assignedCache) { remainingTimeMap.clear(); remainingTimeMap.putAll(this.remainingTimeMap); filledClasses.clear(); filledClasses.addAll(this.filledClasses); filledClasses2.clear(); filledClasses2.putAll(this.filledClasses2); tem.clear(); tem.putAll(this.tem); deviceOccupyMap.clear(); deviceOccupyMap.putAll(this.deviceOccupyMap); assignedCache.clear(); assignedCache.putAll(this.assignedCache); } }解析
最新发布
12-17
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值