【问题标题】:Scan array of doubles in a file | Java扫描文件中的双精度数组 |爪哇
【发布时间】:2020-05-23 18:52:55
【问题描述】:

我试图扫描一个包含双精度数组的文件。我正在使用下面的代码,但它只为每个条目输出0.0。为什么会这样,我该如何解决?

Scanner scanner = new Scanner("file.txt");
double[] array = new double[256 * 256];
for (int i = 0; i < array.length; i++) {
    if (scanner.hasNextDouble()) {
        array[i] = scanner.nextDouble();
    }
}
System.out.println(array[0]);

我正在扫描的文件的一个例子是

0.22131145 0.22131145 0.22131145 0.22841525 0.22841525 ...

【问题讨论】:

  • 添加文件内容也在更新的问题中
  • [ 不被视为有效的数字字符,因此hasNextDouble() 为它返回false。由于扫描仪没有消耗任何数据,hasNextDouble 会一遍又一遍地测试相同的值,直到循环结束。
  • 该数组是如何写入文件的?它是用来表示 JSON 的吗?如果是,则使用 JSON 解析器将其解析回数组。

标签: java arrays file io java.util.scanner


【解决方案1】:

主要问题在于 Scanner 对象的实例化。在这种情况下,您需要将一个File 对象传递给它,而不仅仅是一个字符串,并确保您指定了正确的文件路径。参考官方documentation咨询。

其次,您需要使用 while 循环。 if 语句只会执行一次,但您希望扫描程序在文件中有信息时继续查找。

第三,不要使用数组来存储值。这太冒险了,因为您需要事先知道数组的大小,这意味着您需要循环两次,这将是低效的,或者您正在硬编码,就像您在这里所做的那样。如果有人要从文件中添加或删除值,您将得到意想不到的结果。而是使用动态数据结构,例如 List

public static void main(String[] args) throws FileNotFoundException {
    String filepath = "file.txt";
    Scanner scanner = new Scanner(new File(filepath));
    List<Double> list = new ArrayList<>();

    while (scanner.hasNextDouble()) {
        list.add(Double.valueOf(scanner.next()));
    }

    scanner.close();
    System.out.println(list.get(0));
}

【讨论】:

    【解决方案2】:

    你的代码有四个问题:

    1. 拦截器Scanner 需要 File 对象,但您没有以这种方式使用它。您需要使用以下语法:

      Scanner scanner = new Scanner(new File("file.txt"));
      
    2. 性能:您可以通过在检查i 值的条件中包含scanner.hasNextDouble() 来提高程序的性能,如下所示:

      for (int i = 0; i < array.length && scanner.hasNextDouble(); i++) {
          array[i] = scanner.nextDouble();
      }
      

      这将在scanner.hasNextDouble() 返回false 时立即终止循环;否则,无论scanner.hasNextDouble() 返回的值如何,代码中的循环都将继续运行,直到i &lt; array.length 评估为false

    3. 资源泄漏:您还没有关闭Scanner 对象。在循环结束后添加以下行:

      scanner.close();
      
    4. 缺少功能:您尚未打印完整的数组。您的声明 System.out.println(array[0]) 将仅打印数组中的第一个元素。更改如下以打印完整的数组:

      System.out.println(Arrays.toString(array));
      

      下面给出包含上述所有 cmets 的代码:

      import java.io.File;
      import java.io.FileNotFoundException;
      import java.util.Arrays;
      import java.util.Scanner;
      
      public class Main {
          public static void main(String[] args) throws FileNotFoundException {
              Scanner scanner = new Scanner(new File("file.txt"));
              double[] array = new double[256 * 256];
              for (int i = 0; i < array.length && scanner.hasNextDouble(); i++) {
                  array[i] = scanner.nextDouble();
              }
              scanner.close();
              System.out.println(Arrays.toString(array));
          }
      }
      
    5. 内存利用率:您使用了一个固定大小的数组,如果要存储的元素数量等于数组的大小,这很好。但是,如果不是这种情况(即,如果要存储的元素数量可以小于或大于指定大小),则应使用 Collection 例如ArrayList 是一种动态数组。这将在很多方面为您提供帮助:(a) 如果要存储的元素数量小于指定的大小,您将节省内存 (b) 您不需要更改代码以增加数组的大小您需要存储比您已经指定的更多的元素 (c) Collection 提供了丰富的 API 来处理元素。通过利用此 API,您的代码可以更清晰、更高效、更易于维护等。

      给出下面包含第 5 点的代码:

      import java.io.File;
      import java.io.FileNotFoundException;
      import java.util.ArrayList;
      import java.util.List;
      import java.util.Scanner;
      
      public class Main {
          public static void main(String[] args) throws FileNotFoundException {
              Scanner scanner = new Scanner(new File("file.txt"));
              List<Double> list = new ArrayList<>();
              while (scanner.hasNextDouble()) {
                  list.add(scanner.nextDouble());
              }
              scanner.close();
              System.out.println(list);
          }
      }
      

    【讨论】:

      猜你喜欢
      • 2015-07-13
      • 1970-01-01
      • 2019-08-19
      • 2022-12-22
      • 2019-04-25
      • 1970-01-01
      • 2015-08-20
      • 1970-01-01
      相关资源
      最近更新 更多