如何从存储在文本文件中的数字创建双打数组?

时间:2016-09-24 00:27:16

标签: java arrays

我有一个名为tdata2.txt的文本文件,其中包含多家公司的股票价格数据,如下所示:

Apple
10.1 20 11 21.3 31 12.7 22 32.4 42 13
Microsoft  
23 45.1 78.2 48 93.2 67 86 99.8 22 12
Toyota 
34 76 34.3 67 89.5 23 56 34.9 83 76.1
...

(依此类推)

我想将数字加载到数组中 其中

Double [] Apple = {10.1, 20, 11, 21.3, 31, 12.7, 22, 32.4, 42, 13}

Double [] Microsoft = {23, 45.1, 78.2, 48, 93.2, 67, 86, 99.8, 22, 12}

Double [] Toyota = {34, 76, 34.3, 67, 89.5, 23, 56, 34.9, 83, 76.1}

这是我到目前为止所做的:

    Scanner keyboard = new Scanner(System.in);
    System.out.println("Select A File");
    String FileName = keyboard.next();
    System.out.print(FileName);

    //Stores data from file into array
    BufferedReader br = new BufferedReader(new FileReader(FileName));
    try {
        for (String line; (line = br.readLine()) != null;) {
            System.out.print(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

它可以读入文件并打印出内容,但就此而言。

每家公司不一定有10个号码,有些则有更多的号码。

我正在考虑使用if语句,只要“FileName.hasNextDouble”,然后将其存储到数组中。但我不知道如何跳过公司名称或将公司名称存储为阵列名称。

4 个答案:

答案 0 :(得分:1)

做出的假设:

  • 该文件将始终以公司名称
  • 开头
  • 公司名称后面的行始终是该公司的数据列表(以空格分隔)
  • 数据列表后面的行始终为null或公司名称 如果上述假设成立,我的答案也应该成立。

好的,所以这主要是一个字符串解析问题,而且它实际上相当简单(假设文件格式正确,如果它们不是,那么这可能会很多更加困难)。一般的想法是读取一行,存储公司名称,然后解析下一行的数据并将其放入Map中。请参阅下面的代码。

public static void main(String[] args) {
    String fileName = "..."; //Obtain this however you want

    try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) { //Open a try-with-resource loop. Try-with-resource will close the resource declared in the initial parenthesis automatically.
        Map<String, double[]> data = new HashMap<>(); //Create the mapping of company name -> data
        String line; //Initialize the line variable
        while ((line = reader.readLine()) != null) { //Read a line, while the next line is not null
            String name = line; //Remember the company name
            line = reader.readLine(); //Read the next line, with the data on it
            String[] doubles = line.split(" "); //Split the data into individual elements
            double[] parsedDoubles = new double[doubles.length]; //Create the actual data array, in which the parsed doubles will be stored
            for (int i = 0; i < doubles.length; i++) { //For each data element
                parsedDoubles[i] = Double.parseDouble(doubles[i]); //Parse the double and add it to the array
            }
            data.put(name, parsedDoubles); //Record the array in the map
        }
        double[] toyota = data.get("Toyota"); //Data can now be accessed by calling the get method on map
    } catch (IOException e) { //Catch those pesky IO exceptions
        e.printStackTrace(); //Print those pesky IO exceptions
    }

}

如果我的答案有任何不清楚,或者您不了解(或不熟悉)我正在使用的技术,请发表评论,我会编辑我的答案。

重要提示:这不是一个强大的&#34;或&#34;通用&#34;解。如果这是一个类或一次解析,上面的代码应该没问题,但是如果您正在编写一个长期的应用程序或库,请考虑一般化问题以处理潜在的意外情况(如带有文件的方法)多行数据等。)

答案 1 :(得分:1)

我会全力以赴。有很多变化,我不确定java 8 Stream是否也不是最先进的。

Map<String, List<Double>> mapBrandToCourses = new TreeMap<>();

Path path = Paths.get(fileName);
List<String> lines = Files.readAllLines(path, StandardCharsets.ISO_8859_1);

for (int i = 0; i + 1 < lines.size(); i += 2) {
    String brand = lines.get(i);

    String coursesLine = lines.get(i + 1);
    String[] courseValues = coursesLine.split("\\s+");

    List<Double> courses = Stream.of(courseValues)
        .map(Double::parseDouble)
        .collect(Collectors.toList());

    mapBrandToCourses.put(brand, courses);
} 

这会创建一个品牌名称地图列表中的课程值。寻找 javadoc (在网上)将有很大帮助。

注意:Doubledouble基元类型的对象包装器。除了List这样的容器之外,尽可能使用原始类型。

答案 2 :(得分:0)

您无法使数组具有自定义字符串作为其名称。但是,您可以使用HashMap:

HashMap<String, ArrayList<Double>> companies = new HashMap<>();

BufferedReader br = new BufferedReader(new FileReader(FileName));
try {
    boolean isCompanyLine = True;
    String companyName = '';
    for (String line; (line = br.readLine()) != null;) {

        if (isCompanyLine) {
            companyName = line;
        } else {
            ArrayList<Double> stockPrices = new ArrayList<>();

            for (String price : line.split(' ')) {
                stockPrices.add(Double.parseDouble(price));
            }

            companies.put(companyName, stockPrices);
        }
        isCompanyLine = ! isCompanyLine;
    }

} catch (IOException e) {
    e.printStackTrace();
}

这假设每隔一行都是公司,没有空行,并且股票价格线严格按空格分隔。如果任何这些假设无效,则可以修改此代码。

此外,您可能不想使用双打来存储金钱价值。如果这是一个对金钱至关重要的应用程序,请使用整数或具有任意精度的BigDecimal。

答案 3 :(得分:0)

试试这个。

double[] Apple = {}, Microsoft = {}, Toyota = {};

Path path = Paths.get("stock.txt");
List<String> lines = Files.readAllLines(path);

for (int i = 0, size = lines.size(); i < size; i += 2) {
    double[] stocks = Stream.of(lines.get(i + 1).split("\\s+"))
        .mapToDouble(Double::parseDouble)
        .toArray();
    switch (lines.get(i).trim()) {
    case "Apple" : Apple = stocks; break;
    case "Microsoft" : Microsoft = stocks; break;
    case "Toyota" : Toyota = stocks; break;
    }
}