【问题标题】:Java streams expression parse string to a double[m][n] (with n varying size)Java 流表达式将字符串解析为 double[m][n](n 大小不等)
【发布时间】:2020-10-03 03:34:31
【问题描述】:

作为解析配置字符串的一部分,我想将字符串转换为 double[][] 数组。配置字符串包含一个或多个 (m) 组,每组三个或更多 (n) 个元素。

对于输入:"0,0,0 | 500,0,10 | 0,300,20 | 500,300,30",
我希望输出:double[][]{{0,0,0},{500,0,10},{0,300,20},{500,300,30}}

下面的清单有效,但是,我想改进代码如下(我很难做到):

  1. 使代码通用,用于可变数量的 n 元素,这样它就可以接受诸如“0,0,0 | 500,0,10 | 0,300,20,999 这样的输入 | 500,300,30",其中输出 [2] = [0,300,20,999]。我目前使用的是 (map(x -> new double[]{Double.parseDouble(x[0]),Double.parseDouble(x[1]),Double.parseDouble(x[2])})),我想对其进行一般性重写。
  2. 理想情况下,将两个流表达式合并为一个表达式,将字符串输入并输出 double[m][n] 一次性。这可能吗?

上市:

    String ss = "0,0,0  | 500,0,10  |  0,300,20  | 500,300,30";
    System.out.println(ss);
    
    String[][] result_s = 
            Arrays.
            stream(ss.split("\\|")).
            map(x -> x.trim().split(",")).
            toArray(size -> new String[size][1]);
    double[][] result_d = 
            Arrays.stream(result_s).
            //This next line is the embarrassing part and I would like to make it generic (so independent of number of elements
            map(x -> new double[]{Double.parseDouble(x[0]),Double.parseDouble(x[1]),Double.parseDouble(x[2])})
            .toArray(size -> new double[size][1]);
    
    double[][] result_new = Arrays.stream(ss.split("\\|")).collect(Collectors.toList(entry -> entry.x.trim().split(",")));
            Arrays.
            stream(ss.split("\\|")).
            map(x -> x.trim().split(",")).
            map(x -> new double[]{Double.parseDouble(x[0]),Double.parseDouble(x[1]),Double.parseDouble(x[2])}).
            toArray(size -> new String[size][1]);
    
    //Strings array
    System.out.println("String arrays");
    for(String[] rs : result_s) System.out.println(Arrays.toString(rs));
    
    //double array
    System.out.println("Double arrays");
    for(double[] rs : result_d) System.out.println(Arrays.toString(rs));

输出:

0,0,0 | 500,0,10 | 0,300,20 | 500,300,30
字符串数组
[0, 0, 0]
[500, 0, 10]
[0, 300, 20]
[500, 300, 30]
双数组
[0.0, 0.0, 0.0]
[500.0, 0.0, 10.0]
[0.0, 300.0, 20.0]
[500.0, 300.0, 30.0]

【问题讨论】:

    标签: java arrays lambda java-stream


    【解决方案1】:

    首先,对于“尴尬的台词”,你可以串流每个x,也就是double[]mapToDouble

    .map(x -> Arrays.stream(x).mapToDouble(Double::parseDouble).toArray())
    

    其次,两个流可以非常简单地连接起来。没有toArray(size -> new String[size][1]),第一个流是Stream<String[]>,这也是Arrays.stream(result_s)产生的。

    toArray 将流转换为数组,而Arrays.stream 将数组转换为流,因此Arrays.stream(result_s) 有点撤消toArray(size -> new String[size][1]) 所做的事情。两条线可以相互抵消。

    double[][] result_d =
            Arrays.stream(ss.split("\\|"))
                    .map(x -> x.trim().split(","))
                    .map(x -> Arrays.stream(x).mapToDouble(Double::parseDouble).toArray())
                    .toArray(double[][]::new);
    

    【讨论】:

    • 指定维度[1]没有意义。这会导致为每个流元素分配单个元素 double[] 数组,以便之后被流元素替换。您应该指定一个未初始化的数组,即.toArray(size -> new double[size][]); 或使用更简单的.toArray(double[][]::new);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-20
    • 1970-01-01
    • 2019-06-17
    相关资源
    最近更新 更多