简体   繁体   English

如何转换 ArrayList<string[]> 到包含十进制值的双[]?</string[]>

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

I've taken in my inputs using a buffered reader, like so:我已经使用缓冲阅读器接收了我的输入,如下所示:

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;
}

I have a csv file with values like this:我有一个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

I want to create a double array ( double[] ) so I can run through the file one line at a time in my program.我想创建一个双精度数组( double[] ),这样我就可以在我的程序中一次一行地运行文件。 How can I take the lines from the file and create this array from them?如何从文件中获取行并从中创建此数组?

Assuming that the CSV data are read successfully into List<String[]> , the conversion to 2D double array may be implemented like this using Stream API:假设 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);
}

If a simple double[] array is needed without keeping the lines, the contents of data may be converted using Stream::flatMapToDouble :如果需要一个简单的double[]数组而不保留行,则可以使用Stream::flatMapToDouble转换data的内容:

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

Instead of storing them in an intermediate List<String[]> why not just process them as you read them?与其将它们存储在中间List<String[]>中,不如在阅读它们时直接处理它们?

  • Use Files.lines to read in the lines as a stream.使用Files.lines以 stream 的形式读取行。
  • split each line on a ,在 a 上分割每一行,
  • flatMap to a single stream flatMap到单个 stream
  • convert to a double via Double::parseDouble通过Double::parseDouble转换为双精度
  • and store in an array.并存储在一个数组中。
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));

prints印刷

[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]

Or you can store each line in an array and create a "2D" array.或者您可以将每一行存储在一个数组中并创建一个"2D"数组。

  • Use Files.lines to read in the lines as a stream.使用Files.lines以 stream 的形式读取行。
  • split each line on a ,在 a 上分割每一行,
  • stream the array stream 阵列
  • convert each line to a double array将每一行转换为双精度数组
  • and package all the double arrays into an array of arrays.和 package 所有双 arrays 到 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));
}

prints印刷

[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]

Either way is more efficient by not having to iterate thru the input again.通过不必再次遍历输入,任何一种方式都更有效。

You can use a single Stream for this purpose:为此,您可以使用单个Stream

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]);
        });

Output: Output:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM