如何解决如何在不更改Java本身的哈希图的情况下获取和更改哈希图的值?
我有一个如下的HashMap,
Map<String,MyClass> testMap = new HashMap<>();
map.put("1",myClass1);
map.put("2",myClass2);
MyClass
是一个bean类。现在,我希望获得一个testMap
的值,并在不更改testMap
本身的情况下更改该值。我所做的如下,
MyClass result = testMap.get("1");
if (some conditions){
do someting to result;
}
return result;
我期望result
发生变化,而testMap
保持不变。但实际上myClass1
中的testMap
也会发生变化。那么我如何实现我的目标呢?
解决方法
有多种方法可以实现:
- 从
testMap
中取出一个对象时,请先将其手动复制到相同类型的新对象中。在C ++中,通常使用复制构造函数来实现:new MyClass1(myClass);
,其中复制构造函数将传入的对象的所有字段都复制并复制到新对象中,在Java中,有时使用Cloneable
接口来完成。 - 使您的对象不可变,以使对对象的更改永远不会更改其状态,但始终会返回包含这些更改的新对象。相对较新的示例是
BigDecimal
,其中对BigDecimal
对象的每个操作总是返回一个新的BigDecimal
对象。
可以通过创建不可变对象来实现。更改此对象的值时,它将始终创建一个新对象,并且不会更改原始值。
,MyClass的不变实现:
public class MyClass {
private final String name;
public MyClass(String name) {
this.name = name;
}
/**
* @return the name
*/
public String getName() {
return name;
}
}
客户端验证不变性:
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) {
MyClass myClass = new MyClass("class1");
System.out.println("Object " + myClass);
Map<Integer,MyClass> map = new HashMap<Integer,MyClass>();
map.put(1,myClass);
MyClass result = map.get(1);
System.out.println("From Map Object " + result);
String name = result.getName();
if (name != null && name.equals("class1")) {
MyClass updatedResult = new MyClass("updatedclass1 ");
System.out.println("Updated Object " + updatedResult);
}
System.out.println("From Map Object " + result);
}
}
输出:
Object MyClass@6d06d69c
From Map Object MyClass@6d06d69c
Updated Object MyClass@7852e922
From Map Object MyClass@6d06d69c
更新后的地图保持不变。
,您需要复制MyClass。 如果其中包含对对象的引用,则需要一个深层副本。
在地图中,它存储对对象的引用。因此,当您从地图上获得对该对象的引用并对其进行修改时,您正在修改该对象的相同实例。如果您制作副本,则可以对其中一个进行更改,而对另一个则不能。
浅复制与深复制
浅复制可以使用.clone()完成,但仅复制所有字段,并且如果类中有对象作为字段,则仅复制引用。这是有问题的,因为在每个副本中您将拥有相同的内部对象副本,并且最终会遇到与上述相同的情况-当您修改其中任何一个对象时,也会同时修改其他对象。 / p>
深层复制可缓解此问题,因为它也复制内部对象。 您可以进行递归复制,序列化复制或外部库(例如Apache Commons Lang SerializationUtils.clone())。如果您好奇,此链接将提供更多详细信息。 https://www.baeldung.com/java-deep-copy
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。