HashMap功能' put'工作不正常 - Java

时间:2017-07-11 18:16:00

标签: java hashmap

我正在阅读CSV并将数据保存到对象(为每一行创建一个对象)。 CSV中的行按第一个元素(组号)分组 - 介于2-10行之间的某个行共享一个组号。数据集中有~180个组。为了更容易处理这些数据,我将数据存储到HashMaps中,其中键是组号,与键绑定的值是数据对象的ArrayList。

当我遍历CSV的行时,我将对象添加到HashMap,使用行的组号来指示放置新数据对象的位置。如果对象具有尚未输入CSV的组编号,则会创建一个新密钥(其组编号)和一个仅包含其自身的数据对象的ArrayList。

如果行的组号是HashMap中的一个键,它会将ArrayList绑定到组号,将新数据对象添加到它,并使用put函数重新添加新条目,使用更新的ArrayList(现在还有一个数据条目与共享组号绑定)。

代码示例:

  ArrayList<CSVData> csvListNew = new ArrayList<CSVData>();
  HashMap<Integer,ArrayList<CSVData>> CSVDataMapNew = new HashMap<Integer,ArrayList<CSVData>>();
  while ((line = reader.readLine()) != null && !(line.contains(",,,,,,,,,"))) 
{
            System.out.println(line);
            String[] csvDataNew = line.split(",");
            String currentGroup = csvDataNew[GroupIndex];
            try {
                currentGroupNumber = Integer.parseInt(currentGroup.replace("group", "").replace(" ", ""));
            } catch (Exception ex) {
                currentGroupNumber = previousGroupNumber;
            }
            String path = csvDataNew[PathIndex];
            startLine = Integer.parseInt(csvDataNew[StartLineIndex]);
            endLine = Integer.parseInt(csvDataNew[EndLineIndex]);

            CSVData data = new CSVData(currentGroupNumber, path, startLine, endLine);

            if (CSVDataMapNew.containsKey(currentGroupNumber)) { //if it does contain the current key, add the current object to the ArrayList tied to it.
                csvListNew = CSVDataMapNew.get(currentGroupNumber);
                csvListNew.add(clone);
                CSVDataMapNew.put(currentGroupNumber, csvListNew);
            } else { //if it doesnt contain the current key, make new entry
                csvListNew.add(clone);
                CSVDataMapNew.put(currentGroupNumber, csvListNew);
                System.out.println(CSVDataMapNew.size());
                System.out.println(CSVDataMapNew.get(currentGroupNumber).size());
            }
            csvListNew.clear(); //to make sure no excess objects are entered into the map.
            previousGroupNumber = currentGroupNumber;
        }

有适当的try-catches等,CSVDataTable在它自己的类中声明,静态引用。

问题是,当我在每一步添加print语句时,它就像每个循环结束时擦除HashMap中的每个ArrayList一样。因此,一旦CSV完成迭代,它就有每个键值,但与每个键绑定的ArrayLists都是空的。 (后来通过循环HashMap证明了这一点。)

如何解决这个问题,所以当我在ArrayList中输入一个值并重新放入&#39;关键并将更新后的ArrayList放入Map中,它会保留其数据吗?

3 个答案:

答案 0 :(得分:2)

  

因此,一旦CSV完成迭代,它就会有每个键   值,但绑定到每个键的ArrayLists都是空的。 (

这个

  ArrayList<CSVData> csvListNew = new ArrayList<CSVData>();
应调用

并将其与地图的每个键相关联 但是,您使用ArrayList的单个实例作为地图中每个键的值。

在您的方法结束时,您可以:

 csvListNew.clear(); 

因此,您的地图所有值均为空ArrayList,因为所有值均为ArrayList

要解决您的问题,如果地图中的密钥不存在,您应该创建一个新的ArrayList并将其与此密钥相关联:

  ArrayList<CSVData> csvListNew = CSVDataMapNew.get(currentGroupNumber);

  if (csvListNew == null) 
     csvListNew = new ArrayList<CSVData>();
     CSVDataMapNew.put(csvListNew);
  }

然后重用csvListNew变量来添加元素:

 csvListNew.add(clone);

它简化了具有不良重复的实际代码。

答案 1 :(得分:1)

您始终在python中将相同的ArrayList实例作为值。这是在循环之前创建的HashMap实例,由ArrayList变量引用。

这意味着当您致电csvListNew时,您会清除csvListNew.clear()的所有ArrayList

每次要在HashMap中添加新条目时,都可以通过创建新ArrayList来解决此问题:

HashMap

此外,请删除 if (CSVDataMapNew.containsKey(currentGroupNumber)) { csvListNew = CSVDataMapNew.get(currentGroupNumber); csvListNew.add(clone); } else { csvListNew = new ArrayList<>(); // that's the main required fix csvListNew.add(clone); CSVDataMapNew.put(currentGroupNumber, csvListNew); System.out.println(CSVDataMapNew.size()); System.out.println(CSVDataMapNew.get(currentGroupNumber).size()); } 来电。

答案 2 :(得分:1)

当您从hashMap获取列表时,您将获得对该列表的引用。之后使用此列表执行的所有操作都将影响地图中的列表。这意味着两件事:

  • 在向其添加内容后,您不必将列表重新放回地图
  • 您必须为每个Map条目创建一个新列表。你目前不这样做。

这应该解决它(也是一些调整后的代码风格):

    Map<Integer,List<CSVData>> CSVDataMapNew = new HashMap<>();
    while ((line = reader.readLine()) != null && !(line.contains(",,,,,,,,,")))
    {
        System.out.println(line);
        String[] csvDataNew = line.split(",");
        String currentGroup = csvDataNew[GroupIndex];
        try {
            currentGroupNumber = Integer.parseInt(currentGroup.replace("group", "").replace(" ", ""));
        } catch (Exception ex) {
            currentGroupNumber = previousGroupNumber;
        }
        String path = csvDataNew[PathIndex];
        startLine = Integer.parseInt(csvDataNew[StartLineIndex]);
        endLine = Integer.parseInt(csvDataNew[EndLineIndex]);

        CSVData data = new CSVData(currentGroupNumber, path, startLine, endLine);

        if (CSVDataMapNew.containsKey(currentGroupNumber)) { 
            CSVDataMapNew.get(currentGroupNumber).add(clone);
        } else { 
            ArrayList<CSVData> csvListNew = new ArrayList<CSVData>();
            CSVDataMapNew.put(currentGroupNumber, csvListNew);
            csvListNew.add(clone);
        }
        previousGroupNumber = currentGroupNumber;
    }