如何使用 Java-8 流将 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[][]
转换为 [ 的最佳方法是什么=18=] 使用流? Bar[][][]
到 Foo[][][]
怎么样?
单一维度的转换非常简单。我用于一维数组的代码是:
pubilc static Foo[] convert(Bar[] bars){
return Arrays.stream(bars).mapToObj(Foo::new).toArray(Foo[]::new);
}
这如何在二维中实现? 3 维或 4 维呢?是否可以编写一种递归方法,将一种类型的 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));
}
将它与原始数组一起使用时,您必须使用映射器函数处理最后一个维度(例如 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));
}
我有一个 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[][]
转换为 [ 的最佳方法是什么=18=] 使用流? Bar[][][]
到 Foo[][][]
怎么样?
单一维度的转换非常简单。我用于一维数组的代码是:
pubilc static Foo[] convert(Bar[] bars){
return Arrays.stream(bars).mapToObj(Foo::new).toArray(Foo[]::new);
}
这如何在二维中实现? 3 维或 4 维呢?是否可以编写一种递归方法,将一种类型的 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));
}
将它与原始数组一起使用时,您必须使用映射器函数处理最后一个维度(例如 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));
}