如何将 ArrayList<String[]> 转换为包含十进制值的 double[]?

How can I convert an ArrayList<String[]> to a double[] that contains decimal values?

我使用缓冲 reader 接收输入,如下所示:

private static ArrayList<String[]> dataItem;
private static double[] CONVERT;

public static ArrayList<String[]> readData() throws IOException {
    String file = "numbers.csv";
    ArrayList<String[]> content = new ArrayList<>();
    try (BufferedReader br = new BufferedReader(new FileReader(file))) {
        String line = "";
        while ((line = br.readLine()) != null) {
            content.add(line.split(","));
        }
    } catch (FileNotFoundException e) { }
    return content;
}

我有一个 csv 文件,其值如下:

0.2437,0.2235,0.9,0.2599,0.1051,0.1635,0.3563,0.129,0.1015
0.2441,0.3012,0.9,0.1123,0.1079,0.4556,0.4008,0.3068,0.1061
0.2445,0.4806,0.9,0.1113,0.1081,0.354,0.4799,0.3487,0.1034

我想创建一个双精度数组 (double[]),这样我就可以 运行 在我的程序中一次一行地浏览文件。我怎样才能从文件中提取行并从中创建这个数组?

假设CSV数据成功读入List<String[]>,转换为二维双数组可以使用Stream API:

static double[][] convert2D(List<String[]> data) {
    return data.stream()
        .map(arr -> Arrays.stream(arr)
                .mapToDouble(Double::parseDouble).toArray()) // Stream<double[]>
        .toArray(double[][]::new);
}

如果需要一个简单的 double[] 数组而不保留行,data 的内容可以使用 Stream::flatMapToDouble:

进行转换
static double[] convert1D(List<String[]> data) {
    return data.stream()
        .flatMapToDouble(arr -> Arrays.stream(arr)
                .mapToDouble(Double::parseDouble)) // DoubleStream
        .toArray();
}

与其将它们存储在一个中间体中,不如List<String[]>为什么不在阅读它们的同时处理它们呢?

  • 使用 Files.lines 将行作为流读入。
  • 将每一行拆分为 ,
  • flatMap 到单个流
  • 通过Double::parseDouble
  • 转换为双精度
  • 并存储在数组中。
String file = "numbers.csv";
double[] results1D = null;
try {
    results1D = Files.lines(Path.of(file))
            .flatMap(line -> Arrays.stream(line.split(",")))
            .mapToDouble(Double::parseDouble).toArray();
    
} catch (IOException io) {
    io.printStackTrace();
}
System.out.println(Arrays.toString(results1D));

打印

[0.2437, 0.2235, 0.9, 0.2599, 0.1051, 0.1635, 0.3563, 0.129, 0.1015, 0.2441, 0.3
012, 0.9, 0.1123, 0.1079, 0.4556, 0.4008, 0.3068, 0.1061, 0.2445, 0.4806, 0.9, 0
.1113, 0.1081, 0.354, 0.4799, 0.3487, 0.1034]

或者您可以将每一行存储在一个数组中并创建一个 "2D" 数组。

  • 使用 Files.lines 将行作为流读入。
  • 将每一行拆分为 ,
  • 流式传输数组
  • 将每行转换为双精度数组
  • 并将所有的double数组打包成一个array of arrays
double[][] results2D = null;
try {
    results2D = Files.lines(Path.of(file))
            .map(line -> Arrays.stream(line.split(","))
                    .mapToDouble(Double::parseDouble)
                    .toArray())
            .toArray(double[][]::new);
    
} catch (IOException io) {
    io.printStackTrace();
}
for(double[] d : results2D) {
    System.out.println(Arrays.toString(d));
}

打印

[0.2437, 0.2235, 0.9, 0.2599, 0.1051, 0.1635, 0.3563, 0.129, 0.1015]
[0.2441, 0.3012, 0.9, 0.1123, 0.1079, 0.4556, 0.4008, 0.3068, 0.1061]
[0.2445, 0.4806, 0.9, 0.1113, 0.1081, 0.354, 0.4799, 0.3487, 0.1034]

任何一种方法都更有效,因为不必再次遍历输入。

您可以为此目的使用单个

List<String[]> contents = List.of(
"0.2437,0.2235,0.9,0.2599,0.1051,0.1635,0.3563,0.129,0.1015".split(","),
"0.2441,0.3012,0.9,0.1123,0.1079,0.4556,0.4008,0.3068,0.1061".split(","),
"0.2445,0.4806,0.9,0.1113,0.1081,0.354,0.4799,0.3487,0.1034".split(","));
// convert a List<String[]> to a double[] using a single stream
double[] doubles = contents
        // Stream<String[]>
        .stream()
        // Stream<String>
        .flatMap(Arrays::stream)
        // DoubleStream
        .mapToDouble(Double::parseDouble)
        // double[]
        .toArray();
// output in three lines
IntStream.range(0, doubles.length)
        .forEach(i -> {
            if (i % 9 > 0)
                System.out.print(" ");
            else if (i > 0)
                System.out.println();
            System.out.print(doubles[i]);
        });

输出:

0.2437 0.2235 0.9 0.2599 0.1051 0.1635 0.3563 0.129 0.1015
0.2441 0.3012 0.9 0.1123 0.1079 0.4556 0.4008 0.3068 0.1061
0.2445 0.4806 0.9 0.1113 0.1081 0.354 0.4799 0.3487 0.1034