扫描文件中的双精度数组 |爪哇岛

Scan array of doubles in a file | Java

提问人:Cameron Bhatnagar 提问时间:5/24/2020 最后编辑:Arvind Kumar AvinashCameron Bhatnagar 更新时间:5/24/2020 访问量:782

问:

我试图扫描一个具有双精度数组的文件。我正在使用下面的代码,但它只输出每个条目。为什么会这样,我该如何解决?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 ...
Java 数组 文件 io java.util.scanner

评论

0赞 Nitin Bisht 5/24/2020
在更新的问题中也添加文件内容
0赞 Pshemo 5/24/2020
[不被视为有效的数字字符,因此返回它。由于扫描程序没有消耗任何数据,因此一遍又一遍地测试相同的值,直到循环结束。hasNextDouble()falsehasNextDouble
0赞 Pshemo 5/24/2020
该数组是如何写入文件的?它是否旨在表示 JSON?如果是,请使用 JSON 解析器将其解析回数组。

答:

1赞 cadebe 5/24/2020 #1

主要问题在于 Scanner 对象的实例化。在这种情况下,您需要将一个对象传递到其中,而不仅仅是一个字符串,并确保指定正确的文件路径。有关建议,请参阅官方文档File

其次,您需要使用 while-loop。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));
}
0赞 Arvind Kumar Avinash 5/24/2020 #2

您的代码存在四个问题:

  1. 阻止程序Scanner 需要 File 对象,但您尚未以这种方式使用它。您需要使用以下语法:

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

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

    这将在返回后立即终止循环;否则,代码中的循环将继续运行,直到计算结果为 ,而不管 返回的值如何。scanner.hasNextDouble()falsei < array.lengthfalsescanner.hasNextDouble()

  3. 资源泄漏:您尚未关闭对象。在循环完成后放置以下行:Scanner

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

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

    下面给出了包含上述所有注释的代码:

    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. 内存利用率:您使用了固定大小的数组,如果要存储的元素数等于数组的大小,则可以使用该数组。但是,如果不是这种情况(即,如果要存储的元素数可以小于或大于指定的大小),您应该使用集合,例如 ArrayList,它是一种动态数组。这将在许多方面为您提供帮助: (a) 如果要存储的元素数量小于指定大小,您将节省内存 (b) 当您需要存储比您已经指定的元素更多的元素时,您不需要更改代码来增加数组的大小 (c) 提供丰富的 API 来处理元素。通过利用此 API,您的代码可以清晰、性能更高、更易于管理等。Collection

    下面给出包含第 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);
        }
    }