一起了解原型模式

原型模式

原型模式,用起来其实就是做clone操作,clone一个对象,越过构造器,在特定使用场景下增加效率。

UML

使用场景:

  1. 类初始化需要消耗很多资源,比较耗时。
  2. new方式非常繁琐,还涉及到权限之类的。用clone就减少操作。
  3. 一个对象需要提供给其他对象使用,而且各个使用都可能改到值,可以考虑用原型模式,做保护性拷贝。

先说说原型模式主要的浅拷贝和深拷贝:

浅拷贝:

可被clone的对象:

  • 实现 Cloneable接口
  • 重写clone方法
  • 先clone,再给参数赋值
public class Document implements Cloneable {private String mText;private ArrayList<String> list = new ArrayList<>();public String getmText() {return mText;}public void setmText(String mText) {this.mText = mText;}@Overrideprotected Document clone() throws CloneNotSupportedException {Document document = (Document) super.clone();document.mText = this.mText;document.list = this.list;return document;}
}
复制代码

深拷贝:

对于上面ArrayList,它自身实现类cloneable接口的,所以它本身也是可以clone的,对于对象,赋值后,是指向同一个地址的,对于浅拷贝来说,如果改了list对象,那么原有的对象list也会被修改到。所以对于list对象,我们也需要拷贝一下,修改如下。


public class Document implements Cloneable {private String mText;private ArrayList<String> list = new ArrayList<>();public String getmText() {return mText;}public void setmText(String mText) {this.mText = mText;}@Overrideprotected Document clone() throws CloneNotSupportedException {Document document = (Document) super.clone();document.mText = this.mText;document.list = (ArrayList<String>) this.list.clone();return document;}
}复制代码

检验

首先:对于浅拷贝

  • 我们用下面一段代码来做检验:

Document document = new Document();document.setmText("11111100000");document.getList().add("00");System.out.println("内容原始:" + document.toString());Document document1 = document.clone();document1.setmText("111111");document1.getList().add("111");System.out.println("内容修改:" + document1.toString());System.out.println("内容原始:" + document.toString());复制代码
  • 输出:
内容原始:Document{mText='11111100000', list=[00]}
内容修改:Document{mText='111111', list=[00, 111]}
内容原始:Document{mText='11111100000', list=[00, 111]}
复制代码

这里很明显的能看到,我们改了String类型,也改了list对象。但是输出后,原始的String类型的text没变,但是list却被改变了。 这是为什么呢?

原因其实是: String类型是不可变类型,所以我们不推荐在for循环中使用+号来拼接一样,因为每+一次就会创建一块内存来装。同理,这里的虽然拷贝了string类型,但是第二个对象修改的时候,string的text是指向了新的地址而不是把原地址数据给改了,所以原对象的text并没被改。但list就不一样了,改的是原对象地址的数据 所以我们才会需要深拷贝。

然后我们再检验一次深拷贝的:

输出内容:

内容原始:Document{mText='11111100000', list=[00]}
内容修改:Document{mText='111111', list=[00, 111]}
内容原始:Document{mText='11111100000', list=[00]}复制代码

我们使用深拷贝的时候,将对象list也clone了,就没有指向的不再是原有地址了,所以改动也就影响不到原来数据咯。

另外:实现Cloneable接口只是一种方式。要实现clone也不一定非要实现这个接口(使用Object来重写clone方法的话一定要实现,不然会抛出异常)。

如果使用new的方式并不耗资源等,clone的时候我们传入自己,用new的效率或许会更高:

  public Document(Document document) {this.mText = document.getmText();this.list = document.getList();}@Overridepublic Document clone() throws CloneNotSupportedException {Document document = new Document(this);return document;}
复制代码

总结:原型模式在copy资源非常方便,当然拷贝不一定比new快,所以需要评估测试再考虑是否不用new

转载于:https://juejin.im/post/5b9893f9f265da0aa528f351

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/389702.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++与c语言的区别部分

1.new <malloc> delete <free> 2.多态&#xff1a; 重载 <函数 操作符> 类似于c中的变化参数 虚函数3.模板 4.class类<面向对象> 继承 5.名空间 &#xff08;防止数据冲突问题 &#xff0c; 数据安全&#xff09; 6.引用 &a…

stata中心化处理_带有stata第2部分自定义配色方案的covid 19可视化

stata中心化处理This guide will cover an important, yet, under-explored part of Stata: the use of custom color schemes. In summary, we will learn how to go from this graph:本指南将涵盖Stata的一个重要但尚未充分研究的部分&#xff1a;自定义配色方案的使用。 总而…

5201. 给植物浇水

5201. 给植物浇水 你打算用一个水罐给花园里的 n 株植物浇水。植物排成一行&#xff0c;从左到右进行标记&#xff0c;编号从 0 到 n - 1 。其中&#xff0c;第 i 株植物的位置是 x i 。x -1 处有一条河&#xff0c;你可以在那里重新灌满你的水罐。 每一株植物都需要浇特定…

Anaconda配置和使用

为什么80%的码农都做不了架构师&#xff1f;>>> 原来一直使用原生python和pip的方式&#xff0c;换了新电脑&#xff0c;准备折腾下Anaconda。 安装过程就不说了&#xff0c;全程可视化安装&#xff0c;很简单。 安装后用“管理员权限”打开“Anaconda Prompt”命令…

qml: C++调用qml函数

C调用qml函数&#xff0c;是通过下面的函数实现的&#xff1a; bool QMetaObject::invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type, QGenericReturnArgument ret, QGenericArgument val0 QGenericArgument( Q_NULLPTR ), QGenericArgument val1 QG…

python 插补数据_python 2020中缺少数据插补技术的快速指南

python 插补数据Most machine learning algorithms expect complete and clean noise-free datasets, unfortunately, real-world datasets are messy and have multiples missing cells, in such cases handling missing data becomes quite complex.大多数机器学习算法期望完…

5186. 区间内查询数字的频率

5186. 区间内查询数字的频率 请你设计一个数据结构&#xff0c;它能求出给定子数组内一个给定值的 频率 。 子数组中一个值的 频率 指的是这个子数组中这个值的出现次数。 请你实现 RangeFreqQuery 类&#xff1a; RangeFreqQuery(int[] arr) 用下标从 0 开始的整数数组 ar…

NIO 学习笔记

0. 介绍 参考 关于Java IO与NIO知识都在这里 &#xff0c;在其基础上进行修改与补充。 1. NIO介绍 1.1 NIO 是什么 Java NIO 是 java 1.4, 之后新出的一套IO接口. NIO中的N可以理解为Non-blocking&#xff0c;不单纯是New。 1.2 NIO的特性/NIO与IO区别 IO是面向流的&#x…

[原创]java获取word里面的文本

需求场景 开发的web办公系统如果需要处理大量的Word文档&#xff08;比如有成千上万个文档&#xff09;&#xff0c;用户一定提出查找包含某些关键字的文档的需求&#xff0c;这就要求能够读取 word 中的文字内容&#xff0c;而忽略其中的文字样式、表格、图片等信息。 方案分析…

ab 模拟_Ab测试第二部分的直观模拟

ab 模拟In this post, I would like to invite you to continue our intuitive exploration of A/B testing, as seen in the previous post:在本文中&#xff0c;我想邀请您继续我们对A / B测试的直观探索&#xff0c;如前一篇文章所示&#xff1a; Resuming what we saw, we…

1886. 判断矩阵经轮转后是否一致

1886. 判断矩阵经轮转后是否一致 给你两个大小为 n x n 的二进制矩阵 mat 和 target 。现 以 90 度顺时针轮转 矩阵 mat 中的元素 若干次 &#xff0c;如果能够使 mat 与 target 一致&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输…

samba登陆密码不正确

win7访问Linux Samba的共享目录提示“登录失败&#xff1a;用户名或密码错误”解决方法 解决办法&#xff1a;修改本地安全策略 通过Samba服务可以实现UNIX/Linux主机与Windows主机之间的资源互访&#xff0c;由于实验需要&#xff0c;轻车熟路的在linux下配置了samba服务&…

Java构造函数的深入理解

我们人出生的时候&#xff0c;有些人一出生之后再起名字的&#xff0c;但是有些人一旦出生就已经起好名字的。那么我们在 java 里面怎么在对象一旦创建就赋值呢&#xff1f; public class Person {String name; // 姓名int age; // 年龄public static void main(String[]…

1967. 作为子字符串出现在单词中的字符串数目

1967. 作为子字符串出现在单词中的字符串数目 给你一个字符串数组 patterns 和一个字符串 word &#xff0c;统计 patterns 中有多少个字符串是 word 的子字符串。返回字符串数目。 子字符串 是字符串中的一个连续字符序列。 示例 1&#xff1a;输入&#xff1a;patterns [&…

判断IE版本与各浏览器的语句

---恢复内容开始--- 一.IE下判断IE版本的语句 <!--[if lte IE 6]><![endif]-->IE6及其以下版本可见<!--[if lte IE 7]><![endif]-->IE7及其以下版本可见<!--[if IE 6]><![endif]-->只有IE6版本可见<![if !IE]><![endif]>除了I…

各类软件马斯洛需求层次分析_需求的分析层次

各类软件马斯洛需求层次分析When I joined Square, I was embedded on a product that had been in-market for a year but didn’t have dedicated analytics support.当我加入Square时&#xff0c;我被嵌入了已经上市一年但没有专门的分析支持的产品。 As you might expect,…

384. 打乱数组

384. 打乱数组 给你一个整数数组 nums &#xff0c;设计算法来打乱一个没有重复元素的数组。 实现 Solution class: Solution(int[] nums) 使用整数数组 nums 初始化对象int[] reset() 重设数组到它的初始状态并返回int[] shuffle() 返回数组随机打乱后的结果 示例&#xf…

HTTP/2 学习笔记

创建连接TCP三次握手:包括客户端想服务端发起一个SYN包,接着服务端返回对应SYN的ACK响应以及新的SYN包,然后客户端返回对应的ACK.如果客户端发起HTTPS连接,它还需要进行传输层安全协议(TLS)协商;TLS用来取代安全套接层.HTTP1的问题1.队头阻塞:允许一次发送一组请求,但是只能按照…

MySQL的变量分类总结

在MySQL中&#xff0c;my.cnf是参数文件&#xff08;Option Files&#xff09;&#xff0c;类似于ORACLE数据库中的spfile、pfile参数文件&#xff0c;照理说&#xff0c;参数文件my.cnf中的都是系统参数&#xff08;这种称呼比较符合思维习惯&#xff09;&#xff0c;但是官方…

859. 亲密字符串

859. 亲密字符串 给你两个字符串 s 和 goal &#xff0c;只要我们可以通过交换 s 中的两个字母得到与 goal 相等的结果&#xff0c;就返回 true &#xff1b;否则返回 false 。 交换字母的定义是&#xff1a;取两个下标 i 和 j &#xff08;下标从 0 开始&#xff09;且满足 …