Java - 更新 HashMap 值的最佳方式 - 传递值/引用相关
Posted
技术标签:
【中文标题】Java - 更新 HashMap 值的最佳方式 - 传递值/引用相关【英文标题】:Java - Best way to update HashMap value - Pass by value/reference related 【发布时间】:2014-10-14 00:17:00 【问题描述】:我有一个带有一些数据的 HashMap。看下面的代码...
HashMap<String, Double[]> map; //Already populated with data
Double[] results = map.get(key);
updateArray(results); //This function makes changes to the results array.
map.put(key, results);
...我的问题是 map.put(key, results) 是否必要?
我仍然对 Java 的值传递和引用传递性质有些困惑。需要明确的是,在第一行代码中,我们得到了对 Double 数组的引用,对吗?因此,第二行的函数应该正确地更新 HashMap 中的 Double 数组……这似乎会使第三行的 map.put() 变得多余。
看别人的HashMap相关代码,好像一直在用put()方法。我只是想确保在没有 put() 方法的情况下这样做不会产生任何不可预见的后果。
感谢您的任何意见!
【问题讨论】:
集合和数组混用通常不是一个好主意。 当你写了一个小测试程序来找出答案时发生了什么?至于您对 pass-by-value 与 pass-by-reference(Java 甚至不支持)的混淆,我强烈建议您阅读 this 然后 this。 @BackSlashMap
是一种集合,HashMap
是它的一种实现。
您观察到的使用“put”的示例可能是存储不可变值。他们正在替换它们,而不是修改它们,这需要再次调用“put”
@Fitzy123 我的意思是解决您对其他人使用 HashMap 的观察。您说“他们似乎总是使用 put() 方法。”这很可能是因为存储在其 HashMap 中的值是不可变的,这意味着它们无法更改。对象可以从它们派生出来,但内存中的实际对象不能更改。例如,如果我们想“修改”存储在 HashMap 中的 String,我们可以从中派生另一个 String,但最终我们必须调用“put”来替换原始 String。
【参考方案1】:
考虑以下示例。
Map<String, List<Double>> map = new HashMap<>();
List<Double> list1 = new ArrayList<>();
list1.add(1.0);
list1.add(2.0);
map.put("1", list1);
现在,如果您执行以下操作,地图将自动更新。这是因为 map 持有对实际列表对象的引用。当我们更新相关列表时,map 会在没有任何更新的情况下看到该更改。
List<Double> list2 = map.get("1");
list2.add(10.0);
System.out.println(map);
上面的打印语句将给出以下输出,这将回答问题。
1=[1.0, 2.0, 10.0]
【讨论】:
【参考方案2】:HashMap<String,String> map = new HashMap<>();
map.put("key", "value");
RestAssured.baseURI = BASE_URL;
RequestSpecification request = RestAssured.given();
request.auth().preemptive().basic("Username", "Password").body(map).put("url");
System.out.println("The value of the field after change is: " + map.get("key"));
【讨论】:
您好,如果您能解释一下您的回答,说明您的回答如何/为什么这是给定问题的理想解决方案,并且只发布一些源代码,那就太好了。【参考方案3】:updateArray(results);
这将更新结果对象(其中包含不可变对象的集合,即字符串对象),这意味着当您更新(结果/字符串)对象的值时,它将在结果对象引用下创建另一个字符串。所以如果你想在 map 下看到变化,你必须把它放在 map 中。
my question is whether or not the map.put(key, results) is even necessary?
map.put(key,results); // will only reflect the changes in map
【讨论】:
【参考方案4】:在显示的代码中,完全没有必要。来自map.get(key)
的返回值存储在变量results
中,而results
之后永远不会分配给。因此,传递给map.put()
的results
的值保证与从map.get(key)
得到的值相同。无论类型如何,都是如此。
在这种情况下调用map.put(key, results)
和不调用它略有不同——如果results
(map.get(key)
的结果)是null
,map.put(key, results)
将在其中添加一个null
值以前不在那里。 (HashMap
允许 null
值。)
【讨论】:
【参考方案5】:如果您正在修改您从HashMap
检索到的引用值所引用的对象,那么在同一个HashMap
中替换它的条目是没有意义的。
如果您要修改引用,则确实需要替换它。
【讨论】:
【参考方案6】:map.put(key, results)
仅在 map.get(key)
返回 null 时才是必需的,因为在这种情况下,您应该创建一个新数组并将其放入映射中。
如果map.get(key)
返回一个非空数组,updateArray(results)
将更新该数组,无需再次将相同的数组放入Map
。
所以,总而言之,这段代码涵盖了所有情况:
HashMap<String, Double[]> map; //Already populated with data
...
Double[] results = map.get(key);
if (results == null)
results = new Double[someLength];
map.put(key, results);
updateArray(results);
现在,如果您的 Map 的值是不可变的类,例如 String 或 Integer,您必须在 Map 中放置一个新实例才能替换它,因为您无法更改现有值.
【讨论】:
【参考方案7】:Map.get(Object)
只是返回对所述数组的引用,它不将数组的内容复制到新数组。因此,您对Map.get(Object)
返回的数组所做的任何更改都将反映在存储在Map
中的数组中,因为它们是相同的数组。因此,在这种情况下调用 Map.put(Object,Object)
是完全多余的。
【讨论】:
以上是关于Java - 更新 HashMap 值的最佳方式 - 传递值/引用相关的主要内容,如果未能解决你的问题,请参考以下文章