前几天写程序遇到了这样的一个问题:
Map<String, Object> args=getparameters(); Map<String, Object> hot_args=args; hot_args.put("sortItem","pv"); Map<String, Object> common_args=args; common_args.put("dateId","week");
一直有问题,后来才发现,common_args的sortItem键值和hot_args的键值是一致的,并且在最后,args,hot_args,common_args都是一样的,考虑一番,才想起来这是由于深复制和浅复制的问题:
所谓浅复制:则是只复制对象的引用,两个引用仍然指向同一个对象,在内存中占用同一块内存。被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
深复制:被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
下面是我写的一个实现深复制的案例:(实现对POJO对象的深复制)
package text.copy; public class User implements Cloneable { private String name; private String passwd; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPasswd() { return passwd; } public void setPasswd(String passwd) { this.passwd = passwd; } public Object clone()//重写Cloneable接口的clone()方法 { User user=null; try{ user=(User)super.clone();//将一个实例克隆,并抛出异常 }catch(CloneNotSupportedException e) { e.printStackTrace(); } return user; } }
使用:
User user1=new User(); user1.setName("Lily"); User user2=(User)user1.clone(); user2.setName("admin"); System.out.println("user1.name:"+user1.getName()); System.out.println("user2.name:"+user2.getName());
结果:
user1.name:Lily user2.name:admin
回到最上面,对于Map,我们不好去重写Map类或者HashMap类,但可以通过另外一种方式,HashMap的putAll()来实现:
Map<String, Object> args=getparameters(); Map<String, Object> hot_args=new HashMap<String, Object>(); hot_args.putAll(_args); hot_args.put("sortItem","pv"); Map<String, Object> common_args=new HashMap<String, Object>(); common_args.putAll(_args); common_args.put("dateId","week");
这样,每次都重新创建一个HashMap对象,在改对象上添加键值,三者互不干扰。。。
相关推荐
为了解决这个问题,可以使用序列化和反序列化的方法实现深复制,或者使用第三方库如Apache Commons Lang的`SerializationUtils.clone()`方法。 另外,提到“实现java类之间的多对多联系”,在Java中,多对多关系...
`std::map`在内部会使用复制构造函数来创建键值对的副本,因此如果类没有合适的复制构造函数,编译器将无法正确地处理这些对象。 首先,我们需要理解什么是复制构造函数。复制构造函数是一个特殊的构造函数,它在...
通常,简单的浅复制最快,而深复制和自动化映射工具可能较慢,但更健壮。 综上所述,C#中对象复制和映射有多种实现方式,每种方法都有其适用场景和性能特点。根据项目需求和性能指标,开发者可以选择最适合的映射...
- 当需要对多个对象进行复制时,可以使用上述的工具库,如ModelMapper的`map()`方法可以接受多个源对象和目标对象,一次完成多个对象的复制。 7. **指定复制类型** - 在某些场景下,我们可能需要将源对象的属性值...
通过注解配置,可以指定复制的源类型和目标类型,甚至可以实现复杂的一对多或多对一的映射关系。 6. **性能优化**: 自动化的对象复制通常会比手动复制更高效,因为它可以避免重复的getter和setter调用,尤其是在...
在Java中,对象的复制分为浅复制和深度复制两种。浅复制是指创建一个新的对象,并将原对象的非引用类型的字段值复制到新对象中;对于引用类型的字段,只是复制了引用地址,即新旧对象共享同一份数据。而深度复制则是...
- **浅拷贝与深拷贝**:默认情况下,复制构造函数执行的是浅拷贝,只复制对象的成员变量的指针,而不是指针所指向的数据。如果类中有动态分配的资源,需要确保执行深拷贝以避免共享资源和内存泄漏。 - **自赋值优化...
在C++编程中,`Map`是一种非常重要的数据结构,它允许我们以键值对的形式存储数据,其中每个键(key)都是唯一的,并且通过这个键可以快速访问对应的值(value)。`Map`通常用于存储关联数组,它提供了一种灵活的...
总之,C++中的map容器是一个功能强大且高效的工具,适合处理键值对的存储和查找问题。了解并熟练掌握map的使用,能极大地提升编程效率和代码质量。在实际编程中,应根据具体需求选择合适的数据结构和操作方式,以...
"IAR MAP文件分析" IAR MAP文件分析是编译器编译产生的MAP文件分析,文件后缀为.map,可以查看程序代码及数据在内存中的情况。MAP文件是IAR编译器编译生成的文件,记录了程序在内存中的分布情况。 在IAR工程中,...
`Channel`可以从一个源读取数据并写入到另一个目标,而`Buffer`可以存储和传输数据,两者结合可以实现高效的数据传输和复制。 7. **流(Stream) API** Java 8引入的Stream API也支持数据复制。通过`map()`、`filter...
利用ES6中的Map和WeakMap也可以实现深拷贝,它们可以存储键值对并支持任何类型的键。这种方法更灵活,但语法稍显复杂: ```javascript function deepCopy(arr, map = new WeakMap()) { if (arr instanceof Array) ...
- 当涉及到网络传输时,还需要考虑数据的安全性和完整性问题。 #### 五、总结 通过上述步骤,我们可以有效地将`Map`对象转换为字符串,并能够将字符串还原为原来的`Map`结构。这种方法不仅适用于简单的键值对数据...
Java中的Map接口是Java集合框架的重要组成部分,它用于存储键值对的数据结构,其中每个键都是唯一的,并且与一个值相关联。Map集合不同于List,因为它不维护元素的顺序,而是通过键来访问其对应的值。本文将详细介绍...
此外,可以使用`putAll(map2)`方法将一个Map的所有键值对复制到另一个Map中,如`explicitMap = new TreeMap(); explicitMap.putAll(map)`。 比较Map是否相等,可以使用`==`运算符,它会检查两个Map的键值对是否完全...
map 和 bean 之间的转换,可以利用反射的原理实现
RAMMap是一款强大的内存分析工具,由微软的 Sysinternals 团队开发,主要用于分析和理解操作系统的内存使用情况。这个工具能够帮助用户深入洞察系统内存的分配和使用,包括物理内存、分页文件以及系统缓存等。在标题...
通过其强大的数据分析和可视化能力,用户可以对复杂的空间信息进行深入研究,为决策提供科学依据。 总的来说,GEOMAP3.5凭借其易安装、免许可证的特点,成为了一款深受用户喜爱的GIS工具。无论是初学者还是专业人士...
而"obsidian-mind-map"插件的出现,更是将思维导图这一经典工具融入到Obsidian之中,让知识的可视化变得更加直观和便捷。 首先,让我们了解一下Obsidian。这款应用基于Markdown语法,让用户能够轻松地编辑文本,...
`putAll(Map t)`方法用于将一个Map的所有映射复制到另一个Map,虽然它的效率并不总是高于连续多次调用`put()`,但在调整Map大小方面可能会有所优势。 **查看和遍历Map** Map中的元素不能像List那样直接通过索引来...