zoukankan      html  css  js  c++  java
  • design_model(4)prototype

    1.原型模式

    使用原型实例复制来创建新的对象。

    2.利用Cloneable接口

    浅复制

    //需要实现Cloneable接口,否则不能克隆
    public class PersonTest implements Cloneable {
    	private ArrayList<String> hobby;
    
    	public ArrayList<String> getHobby() {
    		return hobby;
    	}
    
    	public void setHobby(ArrayList<String> hobby) {
    		this.hobby = hobby;
    	}
    
    	@Override
    	protected Object clone() throws CloneNotSupportedException {
    		return super.clone();
    	}
    
    }
    
    public class CloneObjectMethodTest {
    	 public static void main(String[] args) throws CloneNotSupportedException {
    		  ArrayList<String> hobby = new ArrayList<>();
    		  hobby.add("lili");
    		  PersonTest person = new  PersonTest();
    		  person.setHobby(hobby);
    		  /*浅复制,说明:例如String,Integer等不会出现问题的原因是使用了常量池技术,
    		   * 他们直接指向的是常量池的结果而不是引用,当是其他的对象(未使用常量池的对象)时,
    		   * 那么就指向的是引用,解决的方法将使用的引用对象依次复制
    		  */
    		  PersonTest clone = (PersonTest)person.clone();
    		  hobby.set(0, "sansan");
    		  System.out.println(person.getHobby().get(0));//sansan
    		  System.out.println(clone.getHobby().get(0));//sansan
    	}
    }
    

     深复制

    //需要实现Cloneable接口,否则不能克隆
    public class PersonTest implements Cloneable {
    	private static final String Person = null;
    	private ArrayList<String> hobby;
    
    	public ArrayList<String> getHobby() {
    		return hobby;
    	}
    
    	public void setHobby(ArrayList<String> hobby) {
    		this.hobby = hobby;
    	}
    
    	@Override
    	protected Object clone() throws CloneNotSupportedException {
    		PersonTest clone = (PersonTest) super.clone();
    		clone.hobby = (ArrayList<String>) this.hobby.clone();// 深度克隆,将指向的索引都复制一遍
    		return clone;
    	}
    
    }
    
    public class CloneObjectMethodTest {
    	 public static void main(String[] args) throws CloneNotSupportedException {
    		  ArrayList<String> hobby = new ArrayList<>();
    		  hobby.add("lili");
    		  PersonTest person = new  PersonTest();
    		  person.setHobby(hobby);
    		  PersonTest clone = (PersonTest)person.clone();
    		  hobby.set(0, "sansan");
    		  System.out.println(person.getHobby().get(0));//sansan
    		  System.out.println(clone.getHobby().get(0));//lili
    	}
    }
    

     3.利用序列化和反序列化实现深复制

    //需要实现Serializable接口,否则不能序列化和反序列化
    public class PersonTest implements Serializable {
    	private static final String Person = null;
    	private ArrayList<String> hobby;
    
    	public ArrayList<String> getHobby() {
    		return hobby;
    	}
    
    	public void setHobby(ArrayList<String> hobby) {
    		this.hobby = hobby;
    	}
    
    }
    
    public class CloneObjectMethodTest {
    	//序列化和反序列化实现的是深复制,原因是因为都是从文本中读取的,且反序列化是必须有相应的类已经编译,
    	//然后在反序列化的过程中产生了新的对象和赋值动作
    	@SuppressWarnings("resource")
    	public static void main(String[] args) throws CloneNotSupportedException, FileNotFoundException, IOException {
    		ArrayList<String> hobby = new ArrayList<>();
    		hobby.add("lili");
    		PersonTest person = new PersonTest();
    		person.setHobby(hobby);
    		try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("b.txt"))) {
    			oos.writeObject(person);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    
    		try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("b.txt"))) {
    			hobby.set(0, "sansan");
    			PersonTest rdperson = (PersonTest) ois.readObject();
    			System.out.println(person.getHobby().get(0));//sansan
    			System.out.println(rdperson.getHobby().get(0));//lili
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    }
    

     4.原型模式效率比较

    结论:深复制,cloneable最快,Serializable较慢,new最慢

    //New
    public void test(TestClone testClone) {
    		long start = Instant.now().toEpochMilli();
    		for (int i = 0; i < 9; i++) {
    			try {
    				PersonTest1 personTest = new PersonTest1();
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    		long end = Instant.now().toEpochMilli();
    		System.out.println("testNew" + ":" + (end - start));
    }
    
    //testClone
    public void test(TestClone testClone) {
    		long start = Instant.now().toEpochMilli();
    		try {
    			if (!(testClone instanceof PersonTest2)) {
    				return ;
    			}
    			PersonTest2 personTest = (PersonTest2) testClone;
    			ArrayList<String> hobby = new ArrayList<>();
    			personTest.setHobby(hobby);// 1002
    			for (int i = 0; i < 9; i++) {
    				Object clone = personTest.clone();
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		long end = Instant.now().toEpochMilli();
    		System.out.println("testClone" + ":" + (end - start));
    }
    
    //testSerializable
    public void test(TestClone testClone) {
    		long start = Instant.now().toEpochMilli();
    		try {
    			if (!(testClone instanceof PersonTest3)) {
    				return;
    			}
    			PersonTest3 personTest = (PersonTest3) testClone;
    			for (int i = 0; i < 9; i++) {
    				PersonTest3 clonePersonTest = PersonTest3.clonePersonTest(personTest);// 1013
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		long end = Instant.now().toEpochMilli();
    		System.out.println("testSerializable" + ":" + (end - start));
    	}
    
    	public static PersonTest3 clonePersonTest(PersonTest3 person) {
    		try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("b.txt"))) {
    			oos.writeObject(person);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("b.txt"))) {
    			PersonTest3 rdperson = (PersonTest3) ois.readObject();
    			return rdperson;
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return null;
    	}
    
    public class CompareTest implements Runnable {
    	private TestClone testClone;
    
    	public CompareTest(TestClone testClone) {
    		super();
    		this.testClone = testClone;
    	}
    
    	@Override
    	public void run() {
    		try {
    			testClone.test(testClone);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    
    	public static void main(String[] args) throws Exception {
    		ExecutorService fixPool = null;
    		try {
    			fixPool = Executors.newFixedThreadPool(3);
    			fixPool.submit(new CompareTest((TestClone) new PersonTest1()));// testNew:9004
    			fixPool.submit(new CompareTest((TestClone) new PersonTest2()));// testClone:0
    			fixPool.submit(new CompareTest((TestClone) new PersonTest3()));// testSerializable:12
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally {
    			if (fixPool != null) {
    				fixPool.shutdown();
    			}
    		}
    	}
    
    }
    
  • 相关阅读:
    MP4文件格式
    ASP.net 学习路线(详细)
    H.264开源解码器评测
    H264编码 封装成MP4格式 视频流 RTP封包
    MP4介绍与基本AVC编码(x264)教程
    创建一个简单的WCF程序
    VUE 从零开始 学习笔记 一
    关于阿里云短信接口的使用
    对Ul下的li标签执行点击事件——如何获取你所点击的标签
    二逼程序员与苦逼程序员
  • 原文地址:https://www.cnblogs.com/gg128/p/9552032.html
Copyright © 2011-2022 走看看