一起了解原型模式

原型模式

原型模式,用起來其實就是做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.pswp.cn/news/389702.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/389702.shtml
英文地址,請注明出處:http://en.pswp.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;且滿足 …