Java - 如何在方法里面通过值初始化一个HashMap[重复]。

问题描述 投票:0回答:1

我是一个新的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会有不同的表现?

java hashmap copy clone
1个回答
1
投票

如果你做这样的事情

 studentMap = getStudentWithIdMap();

变量studentMap将指向 Map 回归 getStudentwithIdMap(); 中引用的地图。studentMapPrepareData 方法。

要真正改变这种情况 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, ...);
}

1
投票

你的代码对我来说没有什么意义。

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.

© www.soinside.com 2019 - 2024. All rights reserved.