Java HashMap为给定的键给出了错误的值

时间:2019-11-28 09:55:12

标签: java hashmap hash-collision

我正在使用Map<Integer, HashMap<String, List<Employee>>>类型的Map。填充地图后,如果我立即使用String键检索了一些值,则返回的List<Employee>是正确的。但是经过一轮迭代之后,值不断变化。

第一次填充地图后,我没有在任何地方使用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;
}

1 个答案:

答案 0 :(得分:0)

  • dataMap 只需在循环外实例化一次。
  • 使用时应为 e ,您应确保发布的任何代码都可以编译(至少!)
  • detailsMap.put(dataMapKey, keyList);不正确,应为detailsMap.put(e.getDepartment(), keyList);

我认为您的代码应该是这样。现在,它将编译并正确创建您的地图。我随心所欲地重命名了一些变量,以使其更具可读性。

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;
}

也如评论中所述,可以使用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;
}