使用序列化和反序列化实现深拷贝(简单易懂,直接run!)

使用序列化和反序列化实现深拷贝

功能:利用序列化和反序列化实现深拷贝,直接上代码

1、示例1:深拷贝一个TreeMap<Integer,Object>对象的value,这个value是一个String类型的简单对象

package com.example;

import java.io.*;
import java.util.Map;
import java.util.TreeMap;

public class DeepCopyExample {
	// 深度拷贝工具方法不用改
	public static <T> T deepCopy(T object) throws IOException, ClassNotFoundException {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(bos);
		oos.writeObject(object);
		oos.flush();
		ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
		ObjectInputStream ois = new ObjectInputStream(bis);
		return (T) ois.readObject();
	}

	//只需要根据自己代码功能的不同需求修改
	public static void main(String[] args) {
		TreeMap<Integer, Object> a = new TreeMap<>();
		// 示例:填充数据
		a.put(1, new MySerializableClass("test"));
		
		TreeMap<Integer, Object> b = new TreeMap<>();
		try {
			for (Map.Entry<Integer, Object> entry : a.entrySet()) {
				// 键是Integer,不可变,直接使用;值深度拷贝
				Object copiedValue = deepCopy(entry.getValue());
				b.put(entry.getKey(), copiedValue);
			}
		} catch (IOException | ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		// 测试:修改a中的对象,不影响b
		MySerializableClass objA = (MySerializableClass) a.get(1);
		objA.setName("modified");
		MySerializableClass objB = (MySerializableClass) b.get(1);
		objB.setName("test2");
		System.out.println(objB.getName()); // 输出"test",未受影响
		System.out.println(objA.getName());
	}
}
package com.example;

import java.io.Serializable;// 示例类,需实现Serializable
public class MySerializableClass implements Serializable {
	private String name;
	public MySerializableClass(String name) { this.name = name; }
	public String getName() { return name; }
	public void setName(String name) { this.name = name; }
}

在上述示例代码中,根据不同功能需求修改的部分只有MySerializableClass中的序列化对象的类型,以及main函数中希望被深拷贝的对象以及最终生成的对象类型。

2、示例2:深拷贝一个TreeMap<Integer,Object>对象的value,这个value是一个HashMap<String,Object>类型的嵌套map复杂对象

package com.config;
import java.io.*;
import java.util.*;

/**
 * @author f
 * @date 2025/3/20
 * @Description
 */
public class testDeepCopy {

        // 深度拷贝工具方法不用改
        public static <T> T deepCopy(T object) throws IOException, ClassNotFoundException {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(object);
            oos.flush();
            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            return (T) ois.readObject();
        }

        public static void main(String[] args) {
			//定义一个被深拷贝的对象,并赋值
            TreeMap<Integer, Object> a = new TreeMap<>();
            HashMap<String, Object> content = new HashMap<String, Object>();
            content.put("id","abc");
            content.put("content","123");
            HashMap<String, Object> content2 = new HashMap<String, Object>();
            content2.put("id","def");
            content2.put("content","456");
            HashMap<String, Object> content3 = new HashMap<String, Object>();
            content3.put("id","hij");
            content3.put("content","789");
            a.put(1, new MySerializableClass(content));
            a.put(2, new MySerializableClass(content2));
            a.put(3, new MySerializableClass(content3));
            
            //定义一个每次取出a中一个对象的深拷贝内容后的存储对象b
            TreeMap<Integer, Object> b = new TreeMap<>();
			//定义一个取出a所有深拷贝内容后的存储对象c
            TreeMap<Integer, Object> c = new TreeMap<>();
            
            //循环对每一个a的map对象进行深拷贝
            for(int i = 0; i < a.size(); i++){
                try {
                    for (Map.Entry<Integer, Object> entry : a.entrySet()) {
                        // 键是Integer,不可变,直接使用;值深度拷贝
                        Object copiedValue = deepCopy(entry.getValue());
                        b.put(entry.getKey(), copiedValue);
                    }
                } catch (IOException | ClassNotFoundException e) {
                    e.printStackTrace();
                }

                MySerializableClass objA = (MySerializableClass) a.get(i+1);
                System.out.println(objA.getContent());

                MySerializableClass objB = (MySerializableClass) b.get(i+1);
                System.out.println(objB.getContent());
                
                // 获取 Map
                Map<String, Object> contentMap = objB.getContent();
                if (contentMap.containsKey("content")) {
                    contentMap.remove("content");
                    c.put(i+1,contentMap);
                }
				System.out.println(c);
               
            }
        }
}

上述代码的逻辑为:有一个被深拷贝的map对象a,它的value也是map对象,需要循环序列化和反序列化a的每一个map元素,赋值给map对象b,然后再将所有的对象b循环写入map对象c,最终c中的所有对象即为a中的所有对象深拷贝而来。

<think>好的,用户现在的问题是关于如何在Java使用异步队列化处理来避免观察者模式中的循环调用,并且需要简单易懂的示例代码。我需要回顾之前的对话提供的引用,确保回答准确。首先,用户之前的问题是关于多个观察者互相依赖导致循环调用的情况,我给出了几种解决方案,包括异步队列处理。用户现在特别关注异步队列的方法,需要示例代码。我需要参考用户提供的引用[1]中的WeatherStation类引用[2]提到的异步实现,结合之前的回答中的AsyncWeatherStation示例。用户可能希望代码简单明了,容易理解,所以需要简化之前的示例,同时确保避免循环调用。 接下来,思考异步处理如何防止循环调用。当观察者的更新被放入队列异步处理时,每个更新事件会被顺序执行,而不是立即触发,这样如果在更新过程中又有新的通知,会被加入队列,而不是立即执行,从而打破同步调用的循环链。需要确保示例代码展示如何将通知放入队列,并使用线程池处理。同时,可能需要解释为什么异步队列可以避免循环,比如事件被缓冲,不会立即触发嵌套调用。还要注意用户提到的“简单易懂”,所以代码结构要清晰,注释可能有助于理解。另外,需要引用之前的引用,比如引用[1]中的WeatherStation作为基础类,然后扩展为异步版本。 可能还需要提到关键点,比如线程池的使用、任务队列的缓冲机制,以及如何处理可能的并发问题,但保持示例简洁,避免过多复杂细节。 最后,生成相关问题,考虑用户可能感兴趣的分布式系统、模式区别、延迟评估等,但需要根据当前主题调整,比如异步处理的相关问题,如线程池配置、异常处理等。</think>### Java异步队列化处理观察者模式实现方案 #### 核心设计思路 通过**任务队列**将同步通知改为异步执行,利用`BlockingQueue`缓冲观察者更新事件,使用独立线程处理队列任务,从根本上消除调用栈嵌套导致的循环问题[^1][^2]。 #### 完整示例代码 ```java // 基础观察者接口 interface Observer { void update(String weather); } // 异步被观察者实现 public class AsyncWeatherStation { private final List<Observer> observers = new CopyOnWriteArrayList<>(); private final ExecutorService executor = Executors.newSingleThreadExecutor(); private final BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<>(); private String weather; // 添加观察者 public void addObserver(Observer observer) { observers.add(observer); } // 设置天气并触发异步通知 public void setWeather(String newWeather) { this.weather = newWeather; // 将通知任务加入队列 taskQueue.offer(() -> { for (Observer observer : observers) { observer.update(weather); } }); // 启动异步处理线程 executor.submit(() -> { try { while (!taskQueue.isEmpty()) { Runnable task = taskQueue.take(); task.run(); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }); } } // 示例观察者实现 class Display implements Observer { @Override public void update(String weather) { System.out.println("当前天气: " + weather); } } ``` #### 实现原理说明 1. **任务缓冲队列**:使用`BlockingQueue`存储待处理的观察者通知任务 2. **线程池隔离**:通过`ExecutorService`创建独立线程处理通知任务 3. **序列化执行**:队列保证通知事件按FIFO顺序逐个处理 4. **并发控制**:`CopyOnWriteArrayList`确保观察者列表线程安全 #### 防循环机制验证 当观察者A触发被观察者更新时: ```mermaid sequenceDiagram participant A as 观察者A participant S as AsyncWeatherStation participant Q as 任务队列 A->>S: update() S->>Q: 添加通知任务 Q->>S: 异步处理任务 S->>A: 延迟触发update() ``` #### 关键优势 1. **调用栈解耦**:观察者的update()调用不再直接嵌套 2. **事件序列化**:消除并发修改风险 3. **熔断保护**:队列满时自动阻塞新请求 #### 使用示例 ```java public static void main(String[] args) { AsyncWeatherStation station = new AsyncWeatherStation(); Display display1 = new Display(); Display display2 = new Display(); station.addObserver(display1); station.addObserver(display2); // 触发异步通知 station.setWeather("晴"); station.setWeather("暴雨"); } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值