我很困惑在大多数情况下作为参考,但有时不是,和容器。考虑一下这段代码:
HashMap<Integer,String> x_map = new HashMap<>();
x_map.put(42,"foo");
String g = x_map.get(42);
g = "bar";
System.out.println(g.equalsIgnoreCase(x_map.get(42)));
为什么打印false
?
我找到了正确的方法: How to update a value, given a key in a java hashmap?,但我完全失去了上述原因无法按预期工作的原因。此外,当地图中的对象相当大时,我希望能够仅修改地图中其中一个值的单个成员,目前我不知道如何在不创建新实例的情况下执行此操作并将其放入地图。
答案 0 :(得分:3)
Java 按值传递(请参阅Is Java “pass-by-reference” or “pass-by-value”?)。
这意味着当你做
时Person first = new Person("John");
Person second = first;
你有两个不同的变量,都指向内存中的实例new Person("John")
。但同样,两个变量都是不同:
first ---|
|---> new Person("John")
second ---|
如果您操纵对象本身,则会将更改反映到两个变量:
second.setName("Jane");
System.out.println(first.getName()); // Jane
现在的图表是:
first ---|
|---> new Person("John").setName("Jane")
second ---|
但如果你改变变量指向的位置,显然不会影响其他变量,因为你没有触及他们指向的对象:
second = new Person("Jane");
System.out.println(first.getName()); // John
在该语句之后,您有两个指向不同对象的变量:
first ---> new Person("John")
second ---> new Person("Jane")
让我们将这些知识转移到您的代码中。你写道:
String g = x_map.get(42);
g = "bar";
并且问为什么g = "bar"
不影响地图存储的内容。
如上所述,您只需更改变量g
所指向的位置。您不操纵地图内的对象。图表是第一个:
|---> x_map.get(42)
g ---|
"bar"
然后
x_map.get(42)
g ---|
|---> "bar"
如果要更改对象,则需要直接操作它,而不是仅更改变量引用。像first.setName("Jane")
一样。但是,在Java String
中,不可变。这意味着没有办法操纵String
。像String#replace
这样的方法不会操纵原始字符串,它们总是会创建一个新的String
对象并保持旧的不变。
因此,为了更改地图为其键42
而存储的内容,您只需使用Map#put
方法:
x_map.put(42, "bar");
这会将关键x_map
的{{1}}商店更改为42
。
答案 1 :(得分:0)
原因在@khelwood的评论中给出:
变量由Java中的值指定。 g = x_map.get(42) 将地图中的值分配给变量g。如果你重新分配g, 然后你将g重新分配给不同的值。
如果不是String
我在地图中放置了一些实际上可以修改的东西,那么它就可以正常工作:
public static class Test{
public int x = 5;
}
然后......
HashMap<Integer,Test> x_map = new HashMap<>();
x_map.put(42,new Test());
Test g = x_map.get(42);
g.x = 12;
System.out.println((g.x == x_map.get(42).x) + " " + g.x + " " + x_map.get(42).x);
打印true 12 12
。
答案 2 :(得分:0)
因为您没有更新x_map中42键的值。 为此你应该这样做
X_map.put(42,g)