更紧凑的单位矩阵lambda表达式

时间:2016-01-22 23:05:24

标签: java math lambda java-8 java-stream

我有以下用于创建单位矩阵double[][]的表达式:

public double[][] toArray() {
    double[][] identity = new double[rowDimension][columnDimension];
    range(0, rowDimension).forEach(i -> identity[i][i] = 1);
    return identity;
};

我想知道这是否可以紧凑为一个班轮,同时或更高效?

1 个答案:

答案 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