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+"\n");
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+"\n");
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
*/
可以看出,可以使用序列化和逐个复制引用类型域的方式完成深克隆,其中序列化的方式效率很低。
Java实现深克隆的两种方式的更多相关文章
- 对Java代码加密的两种方式,防止反编译
使用Virbox Protector对Java项目加密有两种方式,一种是对War包加密,一种是对Jar包加密.Virbox Protector支持这两种文件格式加密,可以加密用于解析class文件的j ...
- Java新建线程的两种方式
Java新建线程有两种方式,一种是通过继承Thread类,一种是实现Runnable接口,下面是新建线程的两种方式. 我们假设有个竞赛,有一个选手A做俯卧撑,一个选手B做仰卧起坐.分别为两个线程: p ...
- Java实现多线程的两种方式
实现多线程的两种方式: 方式1: 继承Thread类 A: 自定义MyThread类继承Thread类 B: 在MyThread类中重写run() C: 创建MyThread类的对象 D: 启动线程对 ...
- [Java] HashMap遍历的两种方式
Java中HashMap遍历的两种方式原文地址: http://www.javaweb.cc/language/java/032291.shtml第一种: Map map = new HashMap( ...
- java文件读写的两种方式
今天搞了下java文件的读写,自己也总结了一下,但是不全,只有两种方式,先直接看代码: public static void main(String[] args) throws IOExceptio ...
- K:java中序列化的两种方式—Serializable或Externalizable
在java中,对一个对象进行序列化操作,其有如下两种方式: 第一种: 通过实现java.io.Serializable接口,该接口是一个标志接口,其没有任何抽象方法需要进行重写,实现了Serializ ...
- java 实现websocket的两种方式
简单说明 1.两种方式,一种使用tomcat的websocket实现,一种使用spring的websocket 2.tomcat的方式需要tomcat 7.x,JEE7的支持. 3.spring与we ...
- java实现同步的两种方式
同步是多线程中的重要概念.同步的使用可以保证在多线程运行的环境中,程序不会产生设计之外的错误结果.同步的实现方式有两种,同步方法和同步块,这两种方式都要用到synchronized关键字. 给一个方法 ...
- Java线程创建的两种方式
java多线程总结一:线程的两种创建方式及优劣比较 (一)---之创建线程的两种方式 java实现多线程的两种方法的比较
随机推荐
- Vusual C++连接Mysql和从MySql中取出数据的API介绍
.1 mysql_real_connect() 2.1.1 函数原型: MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const ...
- python 遍历删除日志
#! /usr/bin/python2.6#-*- encoding:UTF-8 -*- import osimport os.pathimport time root_dir = os.getcwd ...
- RGPJS 教程之八 创造场景
开始画面 游戏画面 代码 <!DOCTYPE html> <html> <head> <script src="rpg-beta-2.js" ...
- hdoj 5373 The shortest problem
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5373 一开始想到用整除11的性质去做,即奇位数的和和偶位数的和的差为11的倍数,但估不准数据范围没敢去 ...
- IntegrityError错误
Python插入数据库提交失败,一直走IntegrityError错误,没打印错误信息(一定注意编码规范,记住打印错误信息),以为插不进去,弄了好久,最后打印了错误信息 (sqlite3.Integr ...
- Gartner: Hype Cycle for Emerging Technologies-2012 (技术成熟度曲线) [转]
英文稿: The “Hype Cycle for Emerging Technologies” report is the longest-running annual Hype Cycle, p ...
- CloudStack采用spring加载bean(cloud-framework-spring-module模块)
CloudStackContextLoaderListener /* * Licensed to the Apache Software Foundation (ASF) under one * or ...
- SVN备份批处理文件
SVN备份批处理文件,亲测可用 另外,备份文件时获取文件名%%~ni 可改为%%~nxi,以避免文件名中有“.”号时,读取不完成,将.后面的当作后缀名 需要使用hotcopy 时,可以将关键代码进行相 ...
- IIS配置(安装IIS、.Net、更改IIS Log目录位置)
#安装IIS..NetFramework 3.5 Import-Module servermanager Get-WindowsFeature web-* | ? {$_.Name -ne " ...
- Codeforces Round #181 (Div. 2) C. Beautiful Numbers 排列组合 暴力
C. Beautiful Numbers 题目连接: http://www.codeforces.com/contest/300/problem/C Description Vitaly is a v ...