简体   繁体   English

Java HashMap 为给定的键提供错误的值

[英]Java HashMap gives wrong values for the given key

I am using a Map of type Map<Integer, HashMap<String, List<Employee>>> .我正在使用Map<Integer, HashMap<String, List<Employee>>>类型的Map<Integer, HashMap<String, List<Employee>>> After populating the map, if I immediately retrieve some values using the String key, the returned List<Employee> is correct.填充地图后,如果我立即使用String键检索一些值,则返回的List<Employee>是正确的。 But after some iteration the values are changing.但是经过一些迭代后,这些值正在发生变化。

After populating the map the first time, I have not used map.put anywhere, only used map.get() .第一次填充地图后,我没有在任何地方使用map.put ,只使用了map.get()

private Map<Integer, HashMap<String, List<Employee>>> createDataMap(List<Employee> employeeList) {

    for(Employee e:employeeList){       
        Map<Integer, HashMap<String, List<Employee>>> dataMap = new HashMap<>();
        int level = Integer.parseInt(e.getLevel());
        HashMap<String, List<Employee>> detailsMap = dataMap.get(level);
        if (Objects.isNull(detailsMap)) {
            detailsMap = new HashMap<>();
            dataMap.put(level, detailsMap);
        }
        String deptName = key.getDepartment();
        List<Employee> keyList = detailsMap.get(deptName);
        if (Objects.isNull(keyList)) {
            keyList = new ArrayList<>();
            detailsMap.put(dataMapKey, keyList);
        }
        keyList.add(key);
    }
    return dataMap;
}
  • dataMap needs to be instantiated only once, outside of the loop. dataMap 只需要在循环之外实例化一次。
  • When you use key it should be e , you should make sure whatever code you post compiles (as a minimum!)当您使用key 时,它应该是e ,您应该确保您发布的任何代码都可以编译(至少!)
  • detailsMap.put(dataMapKey, keyList); is not correct, should be detailsMap.put(e.getDepartment(), keyList);不正确,应该是detailsMap.put(e.getDepartment(), keyList);

I think that is what your code should look like.我认为这就是你的代码应该是什么样子。 It now compiles and correctly creates your Map.它现在编译并正确创建您的地图。 I took the liberty to rename some variables to make it more readable.我冒昧地重命名了一些变量以使其更具可读性。

private static Map<Integer, HashMap<String, List<Employee>>> createDataMap2(List<Employee> employeeList) {
    Map<Integer, HashMap<String, List<Employee>>> dataMap = new HashMap<>();

    for(Employee e:employeeList){

        // Get the departments for the employee's level
        int level = Integer.parseInt(e.getLevel());
        HashMap<String, List<Employee>> departmentsEmployeesMapForEmployeeLevel = dataMap.get(level);
        if (Objects.isNull(departmentsEmployeesMapForEmployeeLevel)) {
            departmentsEmployeesMapForEmployeeLevel = new HashMap<>();
            dataMap.put(level, departmentsEmployeesMapForEmployeeLevel);
        }

        // Get the employee list for the employee's department
        String deptName = e.getDepartment();
        List<Employee> employeesListForEmployeeLevelAndDepartment = departmentsEmployeesMapForEmployeeLevel.get(deptName);
        if (Objects.isNull(employeesListForEmployeeLevelAndDepartment)) {
            employeesListForEmployeeLevelAndDepartment = new ArrayList<>();
            departmentsEmployeesMapForEmployeeLevel.put(deptName, employeesListForEmployeeLevelAndDepartment);
        }

        // add the employee to its department list
        employeesListForEmployeeLevelAndDepartment.add(e);
    }

    return dataMap;
}

Also as mentioned in the comments, this can be further simplified using Map.getOrDefault .同样如评论中所述,这可以使用Map.getOrDefault进一步简化。

private static Map<Integer, HashMap<String, List<Employee>>> createDataMap2(List<Employee> employeeList) {
    Map<Integer, HashMap<String, List<Employee>>> dataMap = new HashMap<>();

    for(Employee employee: employeeList){
        int level = Integer.parseInt(employee.getLevel());
        String deptName = employee.getDepartment();

        // get the list of department employees for level
        HashMap<String, List<Employee>> departmentsEmployeesMapForEmployeeLevel = 
                dataMap.getOrDefault(level, new HashMap<>());
        // get the list of employees for level and department
        List<Employee> employeesListForEmployeeLevelAndDepartment = 
                departmentsEmployeesMapForEmployeeLevel.getOrDefault(deptName, new ArrayList<>());

        // add employee to its department for its level
        employeesListForEmployeeLevelAndDepartment.add(employee);
        // set new employee list to the employee's department
        departmentsEmployeesMapForEmployeeLevel.put(deptName, employeesListForEmployeeLevelAndDepartment);
        // set the updated department to the employee's level
        dataMap.put(level, departmentsEmployeesMapForEmployeeLevel);
    }

    return dataMap;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM