我是一个新的Java,我尝试了几个方法来初始化我的HashMap通过一个方法,但每次方法执行后,我的地图仍然是空的,我可以调试,并看到在我的 LoadData
方法执行时,我的地图是用子方法的值来分配的,但是,当跳出 LoadData
我的外参数又变成了空地图
// file1.java
public Map<String, Student> getStudentWithIdMap() { ... }
public Map<String, Teacher> getTeacherWithIdMap() { ... }
public static void LoadData(Map<String, Student> studentMap, Map<String, Teacher> teacherMap, ...other Map)
{
studentMap = getStudentWithIdMap();
//I tried with studentMap.putAll(getStudentWithIdMap());
// doing this triggers an exception like "UnsupportedOperationException"
// I also tried studentMap = new HashMap<>(getStudentWithIdMap());
teacherMap = getTeacherWithIdMap();
}
// file2.java
public void PrepareData() {
Map<String, Student> studentMap = Collections.emptyMap();
Map<String, Teacher> teacherMap = Collections.emptyMap();
file1.LoadData(studentMap, teacherMap, ...);
}
遇到上述情况的原因和最佳处理方法是什么?
我知道Java总是把方法当作值类型,所以如果传递一个类对象并修改它的值,在方法执行完毕后,它就会被修改,为什么Map会有不同的表现?
如果你做这样的事情
studentMap = getStudentWithIdMap();
变量studentMap将指向 Map
回归 getStudentwithIdMap();
中引用的地图。studentMap
在 PrepareData
方法。
要真正改变这种情况 Map
你需要在其中插入数值。
例如,用:
public static void LoadData(Map<String, Student> studentMap, Map<String, Teacher> teacherMap, ...other Map)
{
studentMap.putAll( getStudentWithIdMap() );
//I tried with studentMap.putAll(getStudentWithIdMap());
// doing this triggers an exception like "UnsupportedOperationException"
// I also tried studentMap = new HashMap<>(getStudentWithIdMap());
teacherMap.putAll( getTeacherWithIdMap() );
}
这将会导致另一个问题,因为你在初始化这些变量时使用了 Collection.emptyMap()
. 你不允许更改该地图,所以写入会失败。
这可以通过以下方法解决。
public void PrepareData() {
Map<String, Student> studentMap = new HashMap<>();
Map<String, Teacher> teacherMap = new HashMap<>();
file1.LoadData(studentMap, teacherMap, ...);
}
你的代码对我来说没有什么意义。
public static void LoadData(Map<String, Student> studentMap,
Map<String, Teacher> teacherMap, ...other Map) {
studentMap = getStudentWithIdMap();
那个赋值是对一个参数的赋值。 它是一个引用赋值。 它不会影响作为参数传递的map。
<Emphasis>
Java是逐值传递,不是逐引用传递。</Emphasis>
//I tried with studentMap.putAll(getStudentWithIdMap());
// doing this triggers an exception like "UnsupportedOperationException"
这很可能是因为 Collections.emptyMap()
返回一个 不变 空地图。 你是想给它添加元素。 这是不可能的。
创建空的可变地图的方法是使用 new HashMap<>()
或类似。
// I also tried studentMap = new HashMap<>(getStudentWithIdMap());
这失败的原因是你当前的尝试失败了。 你正在创建一个新的地图,并将其分配给一个参数变量......当你返回到 LoadData
.
解决办法是什么?
可能改变
Map<String, Student> studentMap = Collections.emptyMap();
到
Map<String, Student> studentMap = new HashMap<>();
将解决这个问题......但在你的问题中没有足够的上下文来知道这是否是你的问题。纠正 解决办法。 (你到底想在这里做什么? 返回的地图是由 getStudentWithIdMap()
etcetera已经被填充了?)
我知道Java总是把方法当作值型,所以如果传递一个类对象并修改它的值,在方法执行完毕后就会被修改,为什么Map会有不同的表现?
其实,你需要回到课本教程什么的,你在哪里学的。 重新读一遍。 你在原来的阅读理解中忽略了一些很重要的东西。
当你传递一个对象(如a Map
)作为参数时,你是将对象的引用传递给了被调用的方法。 这个引用被分配给一个局部变量。
当你把一个新的引用分配给那个局部变量时,它不会影响原来的对象or你从哪里得到引用的调用器中的变量的状态。
要改变你传递的对象的状态,你使用你传递的引用调用对象上的方法。
顺便说一下 LoadData
是违反风格的。 它应该被命名为 loadData
.