添加新的键值对会在 HashMap 中替换其他键的值

问题描述

所以,我有一个 HashMap 存储每个字符串的数组列表。但是当我用 ArrayList 的新值添加另一对时,其他键值被替换。因此,不同键的所有值都变得相同。

public class Reports{
    
    private ArrayList<Resource> resourceList;
    private HashMap<String,ArrayList<Resource>> consolidatedAttendance = new HashMap<String,ArrayList<Resource>>(); 
    
    public void readReport(String reportFile){
        //initialized with resources from config file
        ArrayList<Resource> repResourceList = new ArrayList<Resource>(getResourceList());

        try (BufferedReader br = new BufferedReader(new FileReader(reportFile))) {
            String line;
            line = br.readLine(); // disregards first line (columns)
            while ((line = br.readLine()) != null) {
                
                if(line.length()==0){
                    break;
                }
                
                //store each resource status in resourceList
                String[] values = line.split(",");      
                String resourceName = values[1],resourceStatus = values[2];
                int resourceIndex = indexOfResource(resourceList,resourceName);
                // to add validation 
                if(resourceIndex!=-1){
                    repResourceList.get(resourceIndex).setStatus(resourceStatus);
                }
                
            }
        }catch(IOException e){
            e.printstacktrace();
        }
        
        
        //get Date
        String reportFilename = reportFile.substring(0,reportFile.indexOf("."));
        String strDate = reportFilename.substring(reportFilename.length()-9);
        consolidateRecords(strDate,new ArrayList<Resource>(repResourceList));
        
    }
    
    
    public void consolidateRecords(String strDate,ArrayList<Resource> repResourceList){
        //consolidate records in hashmap
        consolidatedAttendance.put(strDate,repResourceList);
        
        // test print
        
        for (String key: consolidatedAttendance.keySet()){
            ArrayList<Resource> resources = consolidatedAttendance.get(key);  
            for(Resource resource: resources){
                System.out.println(key+": "+resource.getNickname()+" "+resource.getEid()+" "+resource.getStatus());
            }
        } 
    }
}

所以地图打印时的输出是:

添加的第一个键:

"21-Dec-20": John Working
"21-Dec-20": Alice Working
"21-Dec-20": Jess Working

对于第二个键,列表中存在差异。但, 添加第二个键时(在 put() 方法之后),第一个键的值已被替换。

"21-Dec-20": John SL
"21-Dec-20": Alice Working
"21-Dec-20": Jess SL

"28-Dec-20": John SL
"28-Dec-20": Alice Working
"28-Dec-20": Jess SL

解决方法

您的 Map 的值是 List,其元素与 List 返回的 getResourceList() 的元素相同。您正在创建该 List 的副本(两次)这一事实不会改变这一点。

如果每次调用 getResourceList() 都返回一个包含相同实例的 List,那么您的 Map 中的所有键都将与包含相同实例的不同 List 相关联.