繁体   English   中英

如何使用Java-8 Streams将n维数组映射到另一种类型?

[英]How to map n-Dimensional Array to another type using Java-8 Streams?

我有一个double[][] ,我想将它转换为BigDecimal[][] 可以执行以下操作:

public static BigDecimal[][] convert(double[][] arr1){
    BigDecimal[][] arr2 = new BigDecimal[arr1.length][arr1[0].length];
    for(int i = 0; i < arr1.length; i++){
        for(int j = 0; j < arr1[0].length; j++){
            arr2[i][j] = new BigDecimal(arr1[i][j]);
        }
    }
    return arr2;
}

如何使用Java-8中的流执行此操作?

通常,给定一个类型为Foo的对象,其构造函数采用Bar类型的单个对象,使用流将Bar[][]转换为Foo[][]的最佳方法是什么? Bar[][][]Foo[][][]怎么样?

单个维度的转换是直截了当的。 我用于1D阵列的代码是:

pubilc static Foo[] convert(Bar[] bars){
    return Arrays.stream(bars).mapToObj(Foo::new).toArray(Foo[]::new); 
}

如何在二维中实现这一目标? 三维或四维怎么样? 是否有可能写一个转换一个递归方法n一种类型的维阵列的n另一种类型的维数组?

直截了当的方式:

public static BigDecimal[][] convert(double[][] arr1){
    return Arrays.stream(arr1).map(
        r -> Arrays.stream(r).mapToObj(BigDecimal::new).toArray(BigDecimal[]::new)
    ).toArray(BigDecimal[][]::new);
}

这将从输入数组创建一个Stream<double[]> ,将每个double[]映射到一个BigDecimal[] (通过创建一个DoubleStream并将每个double映射到一个新的BigDecimal ),最后生成一个BigDecimal[][]数组流。


将其扩展为3D数组是相同的逻辑:我们创建输入数组的Stream<double[][]> ,通过前面的代码将每个double[][]转换为BigDecimal[][]并将其转换回数组。

public static BigDecimal[][][] convert(double[][][] arr1){
    return Arrays.stream(arr1).map(r -> convert(r)).toArray(BigDecimal[][][]::new);
}

感谢Holger ,我纠正了我的初始方法,可以将其扩展为具有以下内容的n维数组。 限制是您需要特别注意原始数组。

public static <T> T[] convert(
    Object[] array, Function<Object, Object> mapper, Class<T[]> returnClass) {

    Class componentType = returnClass.getComponentType();
    return Arrays.stream(array)
                 .map(array instanceof Object[][]?
                      r -> convert((Object[])r, mapper, componentType): mapper::apply)
                 .toArray(i -> returnClass.cast(Array.newInstance(componentType, i)));
}

(注意,您可能需要明确地导入java.lang.reflect.Array )。 经过测试

public static void main(String[] args) {
    Double[][] d = { { 0.1 }, { }, { 0.2, 0.3 } };
    BigDecimal[][] bd=convert(d, v -> new BigDecimal((Double) v), BigDecimal[][].class);
    System.out.println(Arrays.deepToString(bd));
}

将它与原始数组一起使用时,必须使用mapper函数处理最后一个维度(例如double[] ),因为一维原始数组不是Object[]实例,并且不能使用通用代码处理。 一个示例用法是

public static void main(String[] args) {
    double[][][] da= { {{ 0.1 }, { }}, {{ 0.2, 0.3 }, { 0.4 }} };
    BigDecimal[][][] bd=convert(da,
      v -> Arrays.stream((double[])v).mapToObj(BigDecimal::new).toArray(BigDecimal[]::new),
      BigDecimal[][][].class);
    System.out.println(Arrays.deepToString(bd));
}

暂无
暂无

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

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