Java - 如何通过值在方法内部初始化一个 HashMap
Java - how to initialize a HashMap inside method by value
我是 Java 的新手,我尝试了几种方法来通过方法初始化我的 HashMap,但是每次执行方法后,我的 Map 仍然是空的,我可以在 LoadData
方法执行,我的maps是从子方法赋值的,但是跳出LoadData
的时候,我的外参又变成空Map了
// 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 始终将方法视为值类型,因此如果传递 class 对象并修改其值,它会在方法完成执行后被修改,为什么 Map 的行为不同?
如果你这样做
studentMap = getStudentWithIdMap();
变量studentMap将通过getStudentwithIdMap();
指向Map
return,不影响PrepareData
中变量studentMap
引用的Map方法。
要实际更改 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();
那个赋值就是给一个参数赋值。这是一个参考任务。它不会影响作为参数传递的地图。
<Emphasis>
Java 是按值传递,而不是按引用传递。 </Emphasis>
//I tried with studentMap.putAll(getStudentWithIdMap());
// doing this triggers an exception like "UnsupportedOperationException"
这很可能是因为 Collections.emptyMap()
return 是一个 不可变的 空映射。您正在尝试向其中添加元素。那不行。
创建空可变映射的方法是使用 new HashMap<>()
或类似方法。
// I also tried studentMap = new HashMap<>(getStudentWithIdMap());
由于您当前的尝试失败,所以失败了。您正在创建一个新地图,并将其分配给一个参数变量......当您从 LoadData
.
return 时,该变量将被丢弃
解决方法是什么?
可能会改变
Map<String, Student> studentMap = Collections.emptyMap();
至
Map<String, Student> studentMap = new HashMap<>();
将解决此问题...但您的问题中没有足够的上下文来判断这是否是 正确的 解决方案。 (你到底想在这里做什么?由 getStudentWithIdMap()
等 return 编辑的地图是否已经填充?)
I get to know Java treats method as value type always, so if passing a class object and modify its value, it would be modified after method finishes execution, why a Map behaves differently?
实际上,你需要回到教科书/教程/任何你学到的地方。重新阅读它。你在原来的阅读/理解中遗漏了一些非常重要的东西。
当您将一个对象(例如 Map
)作为参数传递时,您会将对该对象的引用传递给被调用的方法。该引用被分配给局部变量。
当您为该局部变量分配一个新引用时,它不会影响原始对象的状态或您从中获取引用的调用者中的变量。
要更改您传递的对象的状态,您可以使用您传递的引用调用该对象的方法。
顺便说一句 LoadData
是一种风格违规。它应该被命名为 loadData
.
我是 Java 的新手,我尝试了几种方法来通过方法初始化我的 HashMap,但是每次执行方法后,我的 Map 仍然是空的,我可以在 LoadData
方法执行,我的maps是从子方法赋值的,但是跳出LoadData
的时候,我的外参又变成空Map了
// 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 始终将方法视为值类型,因此如果传递 class 对象并修改其值,它会在方法完成执行后被修改,为什么 Map 的行为不同?
如果你这样做
studentMap = getStudentWithIdMap();
变量studentMap将通过getStudentwithIdMap();
指向Map
return,不影响PrepareData
中变量studentMap
引用的Map方法。
要实际更改 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();
那个赋值就是给一个参数赋值。这是一个参考任务。它不会影响作为参数传递的地图。
<Emphasis>
Java 是按值传递,而不是按引用传递。 </Emphasis>
//I tried with studentMap.putAll(getStudentWithIdMap());
// doing this triggers an exception like "UnsupportedOperationException"
这很可能是因为 Collections.emptyMap()
return 是一个 不可变的 空映射。您正在尝试向其中添加元素。那不行。
创建空可变映射的方法是使用 new HashMap<>()
或类似方法。
// I also tried studentMap = new HashMap<>(getStudentWithIdMap());
由于您当前的尝试失败,所以失败了。您正在创建一个新地图,并将其分配给一个参数变量......当您从 LoadData
.
解决方法是什么?
可能会改变
Map<String, Student> studentMap = Collections.emptyMap();
至
Map<String, Student> studentMap = new HashMap<>();
将解决此问题...但您的问题中没有足够的上下文来判断这是否是 正确的 解决方案。 (你到底想在这里做什么?由 getStudentWithIdMap()
等 return 编辑的地图是否已经填充?)
I get to know Java treats method as value type always, so if passing a class object and modify its value, it would be modified after method finishes execution, why a Map behaves differently?
实际上,你需要回到教科书/教程/任何你学到的地方。重新阅读它。你在原来的阅读/理解中遗漏了一些非常重要的东西。
当您将一个对象(例如 Map
)作为参数传递时,您会将对该对象的引用传递给被调用的方法。该引用被分配给局部变量。
当您为该局部变量分配一个新引用时,它不会影响原始对象的状态或您从中获取引用的调用者中的变量。
要更改您传递的对象的状态,您可以使用您传递的引用调用该对象的方法。
顺便说一句 LoadData
是一种风格违规。它应该被命名为 loadData
.