zoukankan      html  css  js  c++  java
  • Java实现深克隆的两种方式

    序列化和依次克隆各个可变的引用类型都可以实现深克隆,但是序列化的效率并不理想

    下面是两种实现深克隆的实例,并且测试类对两种方法进行了对比:

    1、重写clone方法使用父类中的clone()方法实现深克隆

    package com.lk.B;
    
    public class Worker implements Cloneable{
    	private String name;
    	private int age;
    	public Worker(String name,int age){
    		this.name = name;
    		this.age = age;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public int getAge() {
    		return age;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    	@Override
    	public String toString() {
    		// TODO Auto-generated method stub
    		StringBuffer sb = new StringBuffer();
    		sb.append("姓名:"+name+",");
    		sb.append("年龄:"+age+"
    ");
    		return sb.toString();
    	}
    	@Override
    	protected Worker clone() {
    		// TODO Auto-generated method stub
    		Worker worker = null;
    		try {
    			worker = (Worker) super.clone();
    		} catch (CloneNotSupportedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		return worker;
    	}
    }
    

      2、重写clone()方法使用序列化方法实现深克隆

    package com.lk.B;
    
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    
    public class Employee implements Cloneable,Serializable{
    	private static final long serialVersionUID = 1L;
    	private String name;
    	private int age;
    	public Employee(String name,int age){
    		this.name = name;
    		this.age = age;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public int getAge() {
    		return age;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    	@Override
    	public String toString() {
    		// TODO Auto-generated method stub
    		StringBuffer sb = new StringBuffer();
    		sb.append("姓名:"+name+",");
    		sb.append("年龄:"+age+"
    ");
    		return sb.toString();
    	}
    	@Override
    	protected Employee clone() {
    		// TODO Auto-generated method stub
    		Employee employss = null;
    		
    		ByteArrayOutputStream baos = new ByteArrayOutputStream();
    		try {
    			ObjectOutputStream oos = new ObjectOutputStream(baos);
    			oos.writeObject(this);
    			oos.close();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		
    		ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
    		try {
    			ObjectInputStream ois = new ObjectInputStream(bais);
    			employss = (Employee) ois.readObject();
    			ois.close();
    		} catch (IOException | ClassNotFoundException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		return employss;
    	}
    }
    

      两者的实现方式在上面已经列出来了

    下面编写了一个测试类来测试两种方式的效率

    package com.lk.B;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Test3 {
    	public static void main(String[] args) {
    		List<Worker> workerList = new ArrayList<Worker>();//保存Worker对象
    		List<Employee> employeelist = new ArrayList<Employee>();//保存Employee对象
    		Worker worker = new Worker("阿坤", 21);
    		Employee employee = new Employee("阿坤", 21);
    		long time = System.currentTimeMillis();//取得系统当前时间
    		//保存10000个Worker对象复制品到列表
    		for(int i=0;i<10000;i++){
    			workerList.add(worker.clone());
    		}
    		System.out.println("使用复制域的方式实现克隆所花费的时间:"+(System.currentTimeMillis()-time)+"ms");
    		time = System.currentTimeMillis();//取得系统当前时间
    		//保存10000个Employee对象复制品到列表
    		for(int i=0;i<10000;i++){
    			employeelist.add(employee.clone());
    		}
    		System.out.println("使用复制域的方式实现克隆所花费的时间:"+(System.currentTimeMillis()-time)+"ms");
    	}
    }
    

      运行结果:

    /*
    使用复制域的方式实现克隆所花费的时间:4ms
    使用复制域的方式实现克隆所花费的时间:838ms
    */
    

      可以看出,可以使用序列化和逐个复制引用类型域的方式完成深克隆,其中序列化的方式效率很低。

  • 相关阅读:
    struts2 constant详解
    大图片上传(ImageIO,注意有的图片不能上传时因为他是tiff格式)
    Spring提供的iBatis的SqlMap配置
    2013-7-31hibernate二级缓存
    2013-7-30。。。。难得闲
    POI导出大量数据的简单解决方案
    Tomcat优化详细2
    Tomcat优化详细1
    Tomcat优化方案
    java链表实现
  • 原文地址:https://www.cnblogs.com/luankun0214/p/4398352.html
Copyright © 2011-2022 走看看