我有以下用于创建单位矩阵double[][]
的表达式:
public double[][] toArray() {
double[][] identity = new double[rowDimension][columnDimension];
range(0, rowDimension).forEach(i -> identity[i][i] = 1);
return identity;
};
我想知道这是否可以紧凑为一个班轮,同时或更高效?
答案 0 :(得分:3)
首先,当行计数和列数不相同时(非方矩阵的情况),您的代码会出现问题。循环遍历行但如果行数多于列,则数组索引将超出范围。
您可以创建一个生成所需结果的Stream管道,而不是使用forEach
。在这种情况下,我们需要的是将每一行映射到一个double数组,并将当前行索引的值设置为1.其余元素将设置为0,因为它是{{1的默认值原始的。
这是一个示例代码:
double
public double[][] toArray() {
return IntStream.range(0, Math.min(rowDimension, columnDimension)).mapToObj(r -> {
double[] row = new double[columnDimension];
row[r] = 1;
return row;
}).toArray(double[][]::new);
}
和rowDimension = 3
的输出示例:
columnDimension = 2
这是一个JMH基准测试,比较上面的解决方案,OP问题中的代码和[[1.0, 0.0], [0.0, 1.0], [0.0, 0.0]]
循环等价物。这三种方法在大小为100,1000和3000的方形矩阵上运行。基准测试结果显示上述代码段比其他选项略快( Windows 10,JDK 1.8.0_66,i5-3230M @ 2.60 GHz的):
for
代码:
Benchmark (length) Mode Cnt Score Error Units
StreamTest.toArrayForLoop 100 avgt 50 0,014 ± 0,001 ms/op
StreamTest.toArrayForLoop 1000 avgt 50 1,348 ± 0,028 ms/op
StreamTest.toArrayForLoop 3000 avgt 50 13,588 ± 0,316 ms/op
StreamTest.toArrayStream 100 avgt 50 0,015 ± 0,001 ms/op
StreamTest.toArrayStream 1000 avgt 50 0,788 ± 0,054 ms/op
StreamTest.toArrayStream 3000 avgt 50 8,168 ± 0,459 ms/op
StreamTest.toArrayStreamForEach 100 avgt 50 0,014 ± 0,001 ms/op
StreamTest.toArrayStreamForEach 1000 avgt 50 1,352 ± 0,057 ms/op
StreamTest.toArrayStreamForEach 3000 avgt 50 13,584 ± 0,258 ms/op