【问题标题】:reading a string, int, and double from csv file从 csv 文件中读取字符串、int 和 double
【发布时间】:2014-12-04 18:39:06
【问题描述】:

大家好,我正在尝试从 csv 文件中读取字符串、int 和 double。这是我的 csv 文件中的一个示例:

World Development Indicators
Number of countries,252
CountryName,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012
Aruba,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.029310471,0,0,2.138784453,3.605985937,3.98141538,6.16435217,13.48254011,16.50927821,57.05427692,65.05605558,72.10431377,99.64250268,103.3849507,108.1325002,112.2180618,119.2038996,126.2103374,129.72824,0,131.8565401
Andorra,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.307211734,1.278625641,1.250259142,4.424155104,8.538444783,13.44671556,22.12730607,32.14530928,35.99902139,43.27794118,45.77115817,68.60251444,73.82494308,79.48487497,84.27763597,78.1171579,80.2836099,82.06181111,84.06818386,83.53432222,81.50204186
Afghanistan,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.112598381,0.865196277,2.498055472,4.826865367,9.833164022,17.71624331,29.22037376,37.89493697,45.77817474,60.32631999,60.35299258.

我需要将字符串读入一个名为 String[] countryNames 的数组中,读取年份并将其存储到 int[] yearLabels 中,最后是双精度 double[][] cellularDataTable

我为每个数组创建了一个名为public String[] getCountryNames()public int[] getYearLabel()public data[][] getCellularDataTable() 的函数。我创建了名为Class CSVReader 的类,这些方法在我的类中。在字符串数组函数中,我打算跳过类的第一行并读取行 Number of countries,252 并存储 252 作为字符串数组的大小并将其返回或将每个国家/地区存储到字符串数组中。我的算法是错误的,需要一些指导。 year 函数只是用来读取年份,所以基本上是获取国家的行并存储年份,而 double[][] 函数读取国家和统计数据。因为我会将数组传递到我的 TestClass 中,例如:

 CSVReader parser = new CSVReader(FILENAME);
 String [] countryNames = parser.getCountryNames();
 int [] yearLabels = parser.getYearLabels();
 double [][] parsedTable = parser.getCellularDataTable();

下面是我的 CSVReader 类文件:

import java.io.*;
import java.util.Scanner;

public class CSVReader {
String[] countryNames;
int[] yearNum;
double[][] tables;
Scanner scan;

public CSVReader(String filename)// throws FileNotFoundException 
{ 
    File file = new File(filename);
    try
    {
        scan = new Scanner(file);
    }
    catch(FileNotFoundException e)
    {
        System.out.println(e.getMessage());
    }

}

public String[] getCountryNames()
{
    scan.nextLine();
    while(scan.hasNext())
    {
        final String input = scan.nextLine();
        String[] country = input.split(",");
        //int a = Integer.parseInt(countryNames[1]);
        System.out.println(country[0]);
        int numberOfCountries = Integer.parseInt(country[1]);
    }
    scan.close();
}
public int[] getYearLabels()
{

}
public double[][] getParsedTable()
{

}
}

如果有人可以举例说明如何存储字符串、int 和 double,我相信我可以理解。我想我有我的想法只是不知道如何实现代码。将不胜感激,我是编程新手。谢谢

【问题讨论】:

  • 啊!一个字符串、一个 int 和一个 double 走进了一个 bar...
  • int 表示“我将有一个浮点数”...

标签: java csv


【解决方案1】:

从设计的角度来看,您应该只读取一次文件并存储数据,以便以后可以快速访问它。没有理由将解析分成许多位置。只需一次完成所有解析并将其存储在应该去的地方。

使用您当前的范例,您应该在构造函数中读取所有文件,以便在您开始使用您构建的对象时,所有数据都已读入。

import java.io.*;
import java.util.Scanner;

public class CSVReader {
    String[] countryNames;
    int[] yearNum;
    double[][] tables;

    public CSVReader(String filename) throws FileNotFoundException{ 
        File file = new File(filename);
        Scanner scan = new Scanner(file);
        scan.nextLine(); //Skip the header line

        //Read the int on the next line to allocate arrays
        String numLine = scan.nextLine();
        final int n = Integer.parseInt(numLine.split(",")[1]); //Number is the string portion after the first comma

        //Allocate arrays with length n
        countryNames = new String[n];
        tables = new double[n][];

        //Read in the header line of years, parse and copy into yearNum
        String[] yearHeaders = scan.nextLine().split(",");
        final int m = yearHeaders.length - 1;
        yearNum = new int[m];
        for(int i = 0; i < m; i++){
            yearNum[i] = Integer.parseInt(yearHeaders[i+1]); //i+1 to skip the first entry in the string arr
        }

        //Now read until we run out of lines - put the first in country names and the rest in the table
        int c = 0;
        while(scan.hasNext()){
            String[] inputArr = scan.nextLine().split(",");
            countryNames[c] = inputArr[0];
            tables[c] = new double[m];
            for(int i = 0; i < m; i++){
                tables[c][i] = Double.parseDouble(inputArr[i+1]);
            }
            c++;
        }
        scan.close();
    }

    public String[] getCountryNames(){
        return countryNames;
    }
    public int[] getYearLabels(){
        return yearNum;
    }
    public double[][] getParsedTable(){
        return tables;
    }
}

【讨论】:

  • 这个构造函数迫切需要一个工厂方法:)。而且我认为循环for(int i = 0; i &lt; n; i++) 中有一个错误。终止状态是i&gt;=n,但n 是国家的数量而不是年的数量。这两者之间有关系吗?请阅读这个问题stackoverflow.com/questions/26273850/…,了解为什么while((line = scan.nextLine()) != null) 可能会产生错误。
  • 触及这两个方面。我(错误地)认为国家的数量就是年数,纠正了这一点。此外,我更习惯于 BufferedReader,它在没有更多行可读取时返回 null 而不是抛出,也解决了这个问题。
  • @Tom 是的,你是对的,for 循环中有错误。
  • 不用担心。 OP 提出了一些关于他的项目的问题,他提到 CSV 将包含这么多国家。这就是为什么我知道。是的null,会是更好的方法,但Scanner 开发人员的想法不同。太糟糕了。
  • 现在应该可以了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-13
  • 1970-01-01
  • 2017-12-11
  • 1970-01-01
  • 2019-05-23
相关资源
最近更新 更多