hashmap.clone()返回浅副本,但没有反映价值更改

发布于 2025-02-08 06:56:42 字数 1157 浏览 0 评论 0原文

Java Doc说Hashmap.clone()返回浅副本。

因此,我希望,如果我更改原始hashmap中的某些键的值,克隆的一个将会看到更改。因此,我有一个:

public class ShallowCopy {
    public static void main(String[] args) {
        HashMap<Integer, String> map = new HashMap<Integer, String>();
        map.put(2,"microsoft");
        map.put(3,"yahoo");
        map.put(1,"amazon");

        // Type safety: Unchecked cast from Object to
        // HashMap<Integer, String> Java(16777761)
        Map<Integer, String> mClone = 
            (HashMap<Integer, String>)map.clone();
        String previous = map.replace(3, "google");
        System.out.println(previous); // yahoo
        System.out.println(map.get(3)); // google
        System.out.println(mClone.get(3)); // yahoo, but why?
    }
}

在我的代码中,我称hashmap.replace(),并且我在map中看到了值,从“ yahoo” “ Google”。 奇怪的是,最后一行在mclone中查找它时会打印上一个值。

但是事实是,它正如我预期的那样,它打印“ yahoo”不是“ Google”。 它在哪里弄错了,请友好地解决我的理解?

另外:我在代码(Java(16777761))中发表评论时也收到了一个编译器警告,如何解决?

Java doc says HashMap.clone() returns a shallow copy.

So I expect that if I change the value of some key in original HashMap, the cloned one will also see the change. Thus, I have this:

public class ShallowCopy {
    public static void main(String[] args) {
        HashMap<Integer, String> map = new HashMap<Integer, String>();
        map.put(2,"microsoft");
        map.put(3,"yahoo");
        map.put(1,"amazon");

        // Type safety: Unchecked cast from Object to
        // HashMap<Integer, String> Java(16777761)
        Map<Integer, String> mClone = 
            (HashMap<Integer, String>)map.clone();
        String previous = map.replace(3, "google");
        System.out.println(previous); // yahoo
        System.out.println(map.get(3)); // google
        System.out.println(mClone.get(3)); // yahoo, but why?
    }
}

In my code, I called HashMap.replace() and I see the value in map is changed from "yahoo" to "google".
Strangely, the last line prints the previous value when looking for it in mClone.

But the fact is it prints "yahoo" not "google" as I expected.
Where does it get wrong, please kindly fix my understandings?

Plus: I also got a compiler warning as I commented in my code(Java(16777761)), how to fix it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

囚你心 2025-02-15 06:56:43

tl; dr

克隆操作后,值只是引用同一对象。因此,如果要在一个地图中修改一个参考,则将修改另一个参考。但是您没有修改对象替换的对象。从参考角度来看,它变得不同。

示例

克隆操作正常工作。但是您正在错误地解释结果。考虑以下课程。

class FooClass {
    int a;
    public FooClass(int a) {
        this.a = a;
    }
    public void setA(int a) {
        this.a = a;
    }
    @Override
    public String toString() {
        return a + "";
    }
}

现在创建一个地图及其克隆。

HashMap<Integer, FooClass> map = new HashMap<>();
map.put(10, new FooClass(25));
HashMap<Integer,FooClass> mClone = (HashMap<Integer,FooClass>)map.clone();

每个密钥的值是相同的对象引用。如下所示:

System.out.println(System.identityHashCode(map.get(10)));
System.out.println(System.identityHashCode(mClone.get(10)));

打印,

1523554304
1523554304

因此,如果我修改了一个,它将修改另一个。

对于您的地图的字符串值也是如此。但是,当您用“ Google”替换“ Yahoo”时,您没有修改字符串,而是用其他对象替换了字符串。

如果我要为fuoclass做同样的事情,这就是结果。

System.out.println("Modifying same object");
mClone.get(10).setA(99);
System.out.println(map.get(10));
System.out.println(mClone.get(10));

打印,

Modifying same object
99
99

但如果我要用新对象替换对象。

System.out.println("Replacing the instance");
FooClass previous = mClone.replace(10, new FooClass(1000));
System.out.println("Previous = " + previous);
System.out.println("map: " + map.get(10));
System.out.println("mClone: " + mClone.get(10));

打印

Replacing the instance
Previous = 99
map: 99
mClone: 1000

和后一个操作是您所做的。

TL;DR

After the cloning operation the values are simply references to the same object. So if you were to modify one reference in one map, the other would also be modified. But you didn't modify the object you replaced it. At that point it became distinct from a reference perspective.

Example

The clone operation is working just as you presumed. But you are interpreting the results incorrectly. Consider the following class.

class FooClass {
    int a;
    public FooClass(int a) {
        this.a = a;
    }
    public void setA(int a) {
        this.a = a;
    }
    @Override
    public String toString() {
        return a + "";
    }
}

And now create a map and its clone.

HashMap<Integer, FooClass> map = new HashMap<>();
map.put(10, new FooClass(25));
HashMap<Integer,FooClass> mClone = (HashMap<Integer,FooClass>)map.clone();

The values of each key are the same object reference. As shown by the following:

System.out.println(System.identityHashCode(map.get(10)));
System.out.println(System.identityHashCode(mClone.get(10)));

prints

1523554304
1523554304

So if I modify one, it will modify the other.

The same was true for the String values of your maps. But when you replaced "yahoo" with "google" you didn't modify the String you replaced it with a different Object.

If I were to do the same for FooClass, here is the result.

System.out.println("Modifying same object");
mClone.get(10).setA(99);
System.out.println(map.get(10));
System.out.println(mClone.get(10));

prints

Modifying same object
99
99

But if I were to replace the object with a new one.

System.out.println("Replacing the instance");
FooClass previous = mClone.replace(10, new FooClass(1000));
System.out.println("Previous = " + previous);
System.out.println("map: " + map.get(10));
System.out.println("mClone: " + mClone.get(10));

prints

Replacing the instance
Previous = 99
map: 99
mClone: 1000

And this latter operation is what you did.

烟凡古楼 2025-02-15 06:56:43

方法 clone() 创建 new map ,该 被引用到 values 和< em>键包含在源地图中,它是不是初始映射的视图,而是独立集合

当您调用map.replace(3,“ Google”)映射到键3的值将被新字符串替换,但是克隆地图仍然不受影响,它静止不动地引用了同一字符串“ yahoo”

Method clone() creates a new map which gets populated with references to the values and keys contained in the source map, it's not a view of the initial map but an independent collection.

When you're calling map.replace(3, "google") a value mapped to the key 3 gets replaced with a new string, however the cloned map remains unaffected, it stills holds a reference to the same string "yahoo".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文