【问题标题】:Parsing Large CSV File Where I Only Need The Values in 2 Columns (Java)解析大型 CSV 文件,我只需要 2 列中的值(Java)
【发布时间】:2011-09-15 07:35:11
【问题描述】:

我有一个包含 7 列(见第一行)的 CSV 文件的以下部分,我想将日期(第一列)作为 TreeMap 中的键,并将 Adj Close 值(第 7 列)作为映射值在 TreeMap 中:

日期、开盘价、最高价、最低价、收盘价、成交量、调整收盘价

7/1/2011,132.09,134.1,131.78,133.92,202370700,133.92 2011 年 6 月 30 日,131.14,132.18,130.71,131.97,223496600,131.97 2011 年 6 月 29 日,130.2,130.93,129.63,130.72,244295500,130.72 2011 年 6 月 28 日,128.45,129.63,128.27,129.61,165556300,129.61

在作业的早期部分,我只需将 Open 值(第二列)作为映射值(日期是键)放入 TreeMap 中。我为此使用了 Scanner,我的代码如下:

TreeMap<String, String> loadPriceData(String fileName) throws Exception 
{
     TreeMap<String, String> prices = new TreeMap<String, String>();//create prices map
     Scanner fileScanner = new Scanner(new File(fileName));
     fileScanner.useDelimiter("[,\n]+");// use comma as delimiter
     while(fileScanner.hasNext()) //condition detects comma
     {
         prices.put(fileScanner.nextLine(),fileScanner.nextLine());
     }
     return prices;
}

但这似乎只适用于 2 列 CSV 数据。如果我需要第 7 列中的映射值,那么有效的方法是什么?提前致谢。

【问题讨论】:

  • 为什么不使用开源库进行解析?

标签: csv


【解决方案1】:

您的代码不起作用。分隔符模式不正确。如果您查看地图的内容,您会发现没有日期-价格映射,而是只有一个奇怪的映射。

不使用扫描仪,更简单的方法是逐行读取文件,用逗号分隔每一行,然后将您需要的字段放入地图中。

例如:

public TreeMap<String, String> loadPriceData(String fileName) throws IOException  {
     TreeMap<String, String> prices = new TreeMap<String, String>();// create prices map
     BufferedReader in = null;
     try {
         in = new BufferedReader(new FileReader(fileName));
         String line;

         //read each line in the csv file
         while ((line = in.readLine()) != null) {

             //split line on comma
             String[] fields = line.split(",");

             //put the first and second fields into the map
             prices.put(fields[0], fields[1]);
         }
         return prices;
     } catch (IOException e) {
         throw e;
     } finally {
         if (in != null) {
             try {
                 in.close();
             } catch (IOException e) {// ignore
             }
         }
     }
}

如果您使用的是 Java 7,则可以使用 try-with-resources 语句:

public TreeMap<String, String> loadPriceData(String fileName) throws IOException  {
     TreeMap<String, String> prices = new TreeMap<>();// create prices map
     try (BufferedReader in = Files.newBufferedReader(Paths.get(fileName}),
                                                  Charset.forName("UTF-8"))) {
         String line;

         //read each line in the csv file
         while ((line = in.readLine()) != null) {

             //split line on comma
             String[] fields = line.split(",");

             //put the first and second fields into the map
             prices.put(fields[0], fields[1]);
         }
         return prices;
     } catch (IOException e) {
         throw e;
    }
}

【讨论】:

  • 谢谢,这似乎已经将我需要的数据导入到我的 TreeMap 中。但是,在我使用您的第一个建议解析 CSV 文件后,为什么我的 TreeMap 尚未按照 CSV 文件中显示的排序顺序,我感到很困惑。如果您查看上面我的 CSV 文件的前几行,日期是递减的。但是当我使用迭代器遍历我的 TreeMap 并打印键和值时,它会以完全不同的顺序出现。您对为什么会发生这种情况有任何想法吗?此外,第一行中的标题似乎也不在我的 TreeMap 中。谢谢。
  • 地图根据其键的“自然顺序”进行排序。您的键是字符串,因此地图将执行字符串比较以便对它们进行排序。键按升序返回。如果您希望它们按降序排列,您可以致电prices.descendingMap()。标题在地图中,key=Date,value=Open。​​
  • 好吧,我想我明白了。字符串比较是从左到右的,这就是为什么 1/10/1994 首先出现,然后是 1/10/1995 等等。所以我想需要解析日期,以便关键顺序是 1/10/1994、1/11/1994、1/12/1994 等,尽管这似乎有点棘手,因为你不允许更改“自然订购”?无论如何,我通过使用 if 条件跳过标题行来摆脱标题。谢谢。
  • @dogbane 如果我想要的那些列在这些字段的名称中有逗号。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-09
  • 2018-01-03
  • 2013-10-19
  • 1970-01-01
  • 2013-05-21
相关资源
最近更新 更多