5

我的代码中发生了一件奇怪的事情,我只是不确定发生了什么。我有一个看起来像这样的文件:

id;state;city;total_pop;avg_temp
1;Florida;;120000;76
2;Michigan;Detroit;330000;54
3;New Jersey;Newark;;34

我的 java 解析器应该创建一个映射列表作为结果并返回。但是唯一返回的是文件中的最后一条记录,该记录重复了文件中的行数。有人可以看看我的代码并启发我了解发生了什么吗?先感谢您。

public class FileParserUtil {

    public List<Map<String, String>> parseFile(String fileName, char seperator)
            throws IOException {

        CSVReader reader = new CSVReader(new FileReader(fileName), seperator);
        Map<String, String> record = new HashMap<String, String>();
        List<Map<String, String>> rows = new ArrayList<Map<String, String>>();

        String[] header = reader.readNext();
        String[] nextLine;

        while ((nextLine = reader.readNext()) != null) {
            for (int i = 0; i < header.length; i++) {
                record.put(header[i], nextLine[i]);
            }
            System.out.println("--------Here is the record: ---------");
            System.out.println(record);
            rows.add(record);
            System.out.println("--------Here are the rows: ---------");
            System.out.println(rows);
        }
        reader.close();
        return rows;

    }
}

这是上面从 main 方法运行的控制台输出...

--------Here is the record: ---------
{id=1, avg_temp=76, state=Florida, total_pop=120000, city=}
--------Here are the rows: ---------
[{id=1, avg_temp=76, state=Florida, total_pop=120000, city=}]
--------Here is the record: ---------
{id=2, avg_temp=54, state=Michigan, total_pop=330000, city=Detroit}
--------Here are the rows: ---------
[{id=2, avg_temp=54, state=Michigan, total_pop=330000, city=Detroit}, {id=2, avg_temp=54, state=Michigan, total_pop=330000, city=Detroit}]
--------Here is the record: ---------
{id=3, avg_temp=34, state=New Jersey, total_pop=, city=Newark}
--------Here are the rows: ---------
[{id=3, avg_temp=34, state=New Jersey, total_pop=, city=Newark}, {id=3, avg_temp=34, state=New Jersey, total_pop=, city=Newark}, {id=3, avg_temp=34, state=New Jersey, total_pop=, city=Newark}]
4

4 回答 4

4

我认为您在将记录添加到列表后忘记用新的空地图替换记录。你想要这样的东西:

rows.add(record);
record = new HashMap<String, String>();
于 2013-10-11T12:20:11.300 回答
2
while ((nextLine = reader.readNext()) != null) {
    Map<String, String> record = new HashMap<String, String>();
...
}

您一直在重用同一个地图实例,值会被覆盖。我还建议创建一个单独的类来存储您的数据,这样会更干净。

于 2013-10-11T12:24:15.403 回答
2

这是因为在 HashMap 中你不能有重复的值。所以,当你这样做时

record.put("id","1");

它将检查是否已经有一个名为“id”的键,如果有,它将用新值替换其旧值。在第一次迭代中,它不会替换任何东西,但从下一次迭代开始,它将开始替换旧值。

当你添加

row.add(record);

您一次又一次地添加相同的引用,并且由于地图仅包含新插入的值,toString()因此调用相同的引用的方法并一次又一次地打印相同的值。

你应该添加

record = new HashMap<String,String>();

为每条记录添加新地图。

于 2013-10-11T12:29:58.460 回答
1

您应该移动以下行

Map<String, String> record = new HashMap<String, String>();

在 for 循环内:

public class FileParserUtil {

    public List<Map<String, String>> parseFile(String fileName, char seperator)
            throws IOException {

        CSVReader reader = new CSVReader(new FileReader(fileName), seperator);
        List<Map<String, String>> rows = new ArrayList<Map<String, String>>();

        String[] header = reader.readNext();
        String[] nextLine;

        while ((nextLine = reader.readNext()) != null) {
            Map<String, String> record = new HashMap<String, String>();
            for (int i = 0; i < header.length; i++) {
                record.put(header[i], nextLine[i]);
            }
            System.out.println("--------Here is the record: ---------");
            System.out.println(record);
            rows.add(record);
            System.out.println("--------Here are the rows: ---------");
            System.out.println(rows);
        }
        reader.close();
        return rows;

    }
}
于 2013-10-11T12:23:51.903 回答