47 | 原型模式:如何最快速地clone一个HashMap散列表?
王争
该思维导图由 AI 生成,仅供参考
对于创建型模式,前面我们已经讲了单例模式、工厂模式、建造者模式,今天我们来讲最后一个:原型模式。
对于熟悉 JavaScript 语言的前端程序员来说,原型模式是一种比较常用的开发模式。这是因为,有别于 Java、C++ 等基于类的面向对象编程语言,JavaScript 是一种基于原型的面向对象编程语言。即便 JavaScript 现在也引入了类的概念,但它也只是基于原型的语法糖而已。不过,如果你熟悉的是 Java、C++ 等这些编程语言,那在实际的开发中,就很少用到原型模式了。
今天的讲解跟具体某一语言的语法机制无关,而是通过一个 clone 散列表的例子带你搞清楚:原型模式的应用场景,以及它的两种实现方式:深拷贝和浅拷贝。虽然原型模式的原理和代码实现非常简单,但今天举的例子还是稍微有点复杂的,你要跟上我的思路,多动脑思考一下。
话不多说,让我们正式开始今天的学习吧!
原型模式的原理与应用
如果对象的创建成本比较大,而同一个类的不同对象之间差别不大(大部分字段都相同),在这种情况下,我们可以利用对已有对象(原型)进行复制(或者叫拷贝)的方式来创建新对象,以达到节省创建时间的目的。这种基于原型来创建对象的方式就叫作原型设计模式(Prototype Design Pattern),简称原型模式。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
本文深入介绍了原型模式的应用场景和两种实现方式:深拷贝和浅拷贝。通过一个HashMap散列表的例子,生动阐述了对象创建成本较高且差异不大时,利用原型模式可以节省创建时间的优势。文章重点讲解了深拷贝和浅拷贝的区别,以及在实际应用中需要注意对象的引用关系。此外,还提出了两种深拷贝的实现方法,并探讨了在特定应用场景下如何选择合适的拷贝方式。总的来说,本文内容丰富,对于开发人员快速了解原型模式具有一定的参考价值。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《设计模式之美》,新⼈⾸单¥98
《设计模式之美》,新⼈⾸单¥98
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(91)
- 最新
- 精选
- 冬瓜蔡日常开发中常用的是spring提供的对象之间拷贝的方法: BeanUtils.copyProperties 1、如果是基础类型,则没有问题。 2、如果要拷贝对象里面有小对象,且小对象的全限定名不一样,则拷贝结束后,该对象为null; public class Person { private Photo photo; } 3、如果要拷贝对象里面有集合,集合里面存放的是小对象,则会由于泛型的存在,可以拷贝成功,但是这个拷贝的对象是错误的,会在后续使用过程中产生问题 public class Person { private List<Photo> photo; } 本质上BeanUtils.copyProperties是浅拷贝,在使用过程中需要对嵌套对象或者集合进行额外处理
作者回复: ������
2020-11-1734 - 南北少卿如果对象的创建成本比较大,而同一个类的不同对象之间差别不大(大部分字段都相同) ... 这句话没有想明白
作者回复: 你联系一下上下文看下,都有讲到的
2020-07-05 - 唯她命public class Demo { private ConcurrentHashMap<String, SearchWord> currentKeywords = new ConcurrentHashMap<>(); private long lastUpdateTime = -1; public void refresh() { // 从数据库中取出更新时间>lastUpdateTime的数据,放入到currentKeywords中 List<SearchWord> toBeUpdatedSearchWords = getSearchWords(lastUpdateTime); long maxNewUpdatedTime = lastUpdateTime; for (SearchWord searchWord : toBeUpdatedSearchWords) { if (searchWord.getLastUpdateTime() > maxNewUpdatedTime) { maxNewUpdatedTime = searchWord.getLastUpdateTime(); } } 代码有问题啊, List<SearchWord> toBeUpdatedSearchWords = getSearchWords(lastUpdateTime); toBeUpdatedSearchWords里的数据是改过的数据,时间都大于lastUpdateTime 那为啥下面还要searchWord.getLastUpdateTime() > maxNewUpdatedTime????
作者回复: lastUpdateTime maxNewUpdatedTime searchWord.getLastUpdateTime()三者的关系你理一理
2020-07-052 - L🚲🐱问题 1: 逻辑删除即可 问题 2: 返回深拷贝对象2020-02-19294
- skull原型模式,最为常用经典就是BeanUtils2020-04-2459
- 辣么大问题1: 方法一:新旧的数据取交集,可以删除旧map中的删除关键字,之后的逻辑就和文章中一样了。 方法二:逻辑删除,当map的size中已删除占比过高时,resize map。 争哥说:这里我们利用了 Java 中的 clone() 语法来复制一个对象。如果你熟悉的语言没有这个语法,那把数据从 currentKeywords 中一个个取出来,然后再重新计算哈希值,放入到 newKeywords 中也是可以接受的。 Java HashMap的clone方法就把数据取出来,计算hash值,在放回去的。clone方法中,调用了putMapEntries方法,其中有一关键的一行,克隆重新计算了hash值: putVal(hash(key), key, value, false, evict); 文章中的深复制:为什么SearchWord不重写clone方法呢? @Override protected Object clone() throws CloneNotSupportedException { SearchWord newWord = new SearchWord(this.keyWord, this.times, this.tmstamp); return newWord; }2020-02-19218
- 岁月课堂讨论题 关键字如果支持删除, 最简单高效的方法就是在数据表里加一个delete bool类型的字段, 占用空间不多, 但是很方便程序识别最近更新的数据里面, 有哪条是需要删除的. 不过这样会带来一个问题, 就是插入新关键字的时候, 要先检查一下是否存在同名的关键字, 有的话要把delete字段修改为false, 所以还需要对关键字建立索引, 这样可以高效查找出是否存在同名关键字2020-02-21317
- 新的起点,新的开始^_^我有个问题,最后一种方式使用copy()的浅拷贝+对象替换可以提高效率。但是copy()之后,数据库中更没有发生变化的数据其实newKeywords中指向的还是之前的对象引用啊,不是一个新的对象,那这个结果不久和需求冲突了吗?需求是:任何时刻,系统 A 中的所有数据都必须是同一个版本的。举个例子,比如说我修改了一个newKeywords中value对应的SearchWord对象的某个属性,那么响应的,currentKeywords中肯定也会发生变化,因为SearchWord地址值时一样的,这个就不是刚开始讲的深拷贝得到的是一份完完全全独立的对象,它不是独立的,只有数据库中被更新过的数据是独立的,因为执行了map.remove()和map.put()2020-04-26815
- 安静老师,就是java分层架构中各层的对象,比如VO,BO,PO之间的互相转换,使用的就是原型模式,而做业务开发每天都要与这些打交道。2020-04-08114
- 不似旧日既然说在Java中不常用那我就不看了,以后有时间再学。2020-02-24213
收起评论