如何在Java中获取和修改哈希映射(hashmap)的值,而不改变哈希映射本身?

huangapple go评论72阅读模式
英文:

How to get and change a value of a hashmap, without changing the hashmap itself in Java?

问题

我有一个如下的HashMap,

Map<String, MyClass> testMap = new HashMap<>();
map.put("1", myClass1);
map.put("2", myClass2);

这里MyClass是一个JavaBean类。现在我希望获取testMap的一个值,并且在不改变testMap本身的情况下修改这个值。我所做的操作如下,

MyClass result = testMap.get("1");
if (一些条件){
    对result进行操作;
}
return result;

我期望的是result改变,而testMap保持不变。但实际上,testMap中的myClass1也发生了改变。那么我该如何实现我的目标呢?

英文:

I have a HashMap as follows,

Map&lt;String, MyClass&gt; testMap = new HashMap&lt;&gt;();
map.put(&quot;1&quot;, myClass1);
map.put(&quot;2&quot;, myClass2);

Here MyClass is a bean class. Now I wish to get a value of testMap, and change the value without changing the testMap itself. What I did is as follows,

MyClass result = testMap.get(&quot;1&quot;);
if (some conditions){
    do someting to result;
}
return result;

What I expect is that result changes and testMap keeps unchanged. But actually myClass1 in testMap changes as well. So how can I achieve my goal?

答案1

得分: 1

有多种方法可以实现这个:

  1. 当你从testMap中取出一个对象时,首先要手动将它复制到一个相同类型的新对象中。在C++中,这通常是使用复制构造函数实现的:new MyClass1(myClass);,其中复制构造函数接受传入对象的所有字段,并将其复制到一个新对象中;在Java中,有时会使用Cloneable接口来实现这一点。
  2. 使你的对象不可变,这样对象上的更改永远不会改变其状态,而是始终返回一个包含这些更改的新对象。一个相对较新的示例是BigDecimal,在BigDecimal对象上的每个操作始终返回一个新的BigDecimal对象。
英文:

There are multiple ways to achieve that:

  1. When you take an object out of testMap you first manually copy it into a new object of the same type. In C++ this was commonly implemented using a copy constructor: new MyClass1(myClass); where the copy constructor takes all fields of the object passed in and copies it into a new object, in Java this is sometimes done using the Cloneable interface.
  2. Make your object immutable so that a change on an object never changes its state but always returns a new object that incorporates those changes. A relatively new example is BigDecimal where every operation on a BigDecimal object always returns a new BigDecimal object.

答案2

得分: 0

这可以通过创建不可变对象来实现。当您更改此对象的值时,它将始终创建一个新对象,而不会更改原始值。

英文:

It can be achieved by creating immutable object. When you change the value of this object it will always create a new object and will not change original value.

答案3

得分: 0

Immutable Implementation of MyClass:

public class MyClass {
    private final String name;

    public MyClass(String name) {
        this.name = name;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }
}

Client to verify Immutability:

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);
    }
}

Output:

Object MyClass@6d06d69c
From Map Object MyClass@6d06d69c
Updated Object MyClass@7852e922
From Map Object MyClass@6d06d69c

After update map  remain same.
英文:

Immutable Implementation of MyClass:

public class MyClass {
	private final String name;

	public MyClass(String name) {
		this.name = name;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

}

Client to verify Immutability:

import java.util.HashMap;
import java.util.Map;

public class Test {
	public static void main(String[] args) {
		MyClass myClass = new MyClass(&quot;class1&quot;);
		System.out.println(&quot;Object &quot; + myClass);

		Map&lt;Integer, MyClass&gt; map = new HashMap&lt;Integer, MyClass&gt;();
		map.put(1, myClass);

		MyClass result = map.get(1);
		System.out.println(&quot;From Map Object &quot; + result);
		String name = result.getName();
		if (name != null &amp;&amp; name.equals(&quot;class1&quot;)) {
			MyClass updatedResult = new MyClass(&quot;updatedclass1 &quot;);
			System.out.println(&quot;Updated Object &quot; + updatedResult);
		}
		System.out.println(&quot;From Map Object &quot; + result);

	}
}

Output:

Object MyClass@6d06d69c
From Map Object MyClass@6d06d69c
Updated Object MyClass@7852e922
From Map Object MyClass@6d06d69c

After update map remain same.

答案4

得分: 0

你需要复制我的MyClass。
如果你在其中有对象的引用,你会需要进行深拷贝。

在这个映射内部,它存储了对这些对象的引用。因此,当你从映射中获取对该对象的引用并进行修改时,你实际上是修改了同一个对象的实例。如果你进行复制,你将能够对一个副本进行更改,但另一个副本不会受影响。

浅拷贝与深拷贝

浅拷贝 可以使用 .clone() 方法来实现,但它只会拷贝所有字段,如果类中的字段是对象,那么只会拷贝引用。这是有问题的,因为在每个拷贝中你都将拥有相同的内部对象副本,从而出现与上述相同的情况 - 当你修改任何一个对象时,另一个对象也会被修改。

深拷贝 解决了这个问题,因为它也会拷贝内部对象。
你可以通过递归拷贝、通过序列化进行拷贝,或者使用外部库(比如 Apache Commons Lang 的 SerializationUtils.clone() 方法)。如果你感兴趣,这个链接提供了更多细节。
https://www.baeldung.com/java-deep-copy

英文:

You'll need to make a copy of MyClass.
If you have references to objects within, you'll need a deep copy.

Within the map, it stores references to the objects. So when you get the reference to that object from the map and modify it, you're modifying the same instance of the object. If you make a copy, you'll be able to make changes to one, but not the other.

Shallow Copying vs. Deep Copying

Shallow copying can be done with .clone(), but just copies all of the fields, and if there are objects as fields in the class, only the reference will be copied. This is problematic because you'll have the same copies of the internal objects within each copy, and you'll end up with the same situation as above - when you modify any of those objects, you'll modify the other ones too.

Deep copying alleviates this problem, as it copies internal objects as well.
You can go through and recursively copy, copy through serialization, or external libraries (like Apache Commons Lang SerializationUtils.clone()). This link has some more details if you're curious.
https://www.baeldung.com/java-deep-copy

huangapple
  • 本文由 发表于 2020年9月17日 21:51:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/63939580.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定