你可以有:
public static UnaryOperator<double[][]> transpose() { return m -> { return range(0, m[0].length).mapToObj(r -> range(0, m.length).mapToDouble(c -> m[c][r]).toArray() ).toArray(double[][]::new); };}此代码不使用,
forEach而是使用
mapToObj并将
mapToDouble每行映射到它们的转置。由于返回类型相同,因此我也更改
Function<double[][],double[][]>为
UnaryOperator<double[][]>。
但是,像assylias的答案中那样具有简单的for循环可能不会更有效。
样例代码:
public static void main(String[] args) { double[][] m = { { 2, 3 }, { 1, 2 }, { -1, 1 } }; double[][] tm = transpose().apply(m); System.out.println(Arrays.deepToString(tm)); // prints [[2.0, 1.0, -1.0], [3.0, 2.0, 1.0]]}我已经实现了一个JMH基准测试,可以比较上面的代码,for循环版本和上面的代码并行运行。使用大小分别为100、1000和3000的随机平方矩阵调用这三种方法。结果是,对于较小的矩阵,
for循环版本更快,但是对于较大的矩阵,并行Stream解决方案的性能确实更好(
Windows 10,JDK 1.8.0_66,i5-3230M @ 2.60 GHz ):
Benchmark (matrixSize) Mode Cnt Score Error UnitsStreamTest.forLoopTranspose 100 avgt 30 0,026 ± 0,001 ms/opStreamTest.forLoopTranspose 1000 avgt 30 14,653 ± 0,205 ms/opStreamTest.forLoopTranspose 3000 avgt 30 222,212 ± 11,449 ms/opStreamTest.parallelStreamTranspose100 avgt 30 0,113 ± 0,007 ms/opStreamTest.parallelStreamTranspose 1000 avgt 30 7,960 ± 0,207 ms/opStreamTest.parallelStreamTranspose 3000 avgt 30 122,587 ± 7,100 ms/opStreamTest.streamTranspose 100 avgt 30 0,040 ± 0,003 ms/opStreamTest.streamTranspose 1000 avgt 30 14,059 ± 0,444 ms/opStreamTest.streamTranspose 3000 avgt 30 216,741 ± 5,738 ms/op
基准代码:
@Warmup(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)@BenchmarkMode(Mode.AverageTime)@OutputTimeUnit(TimeUnit.MILLISECONDS)@Fork(3)public class StreamTest { private static final UnaryOperator<double[][]> streamTranspose() { return m -> { return range(0, m[0].length).mapToObj(r -> range(0, m.length).mapToDouble(c -> m[c][r]).toArray() ).toArray(double[][]::new); }; } private static final UnaryOperator<double[][]> parallelStreamTranspose() { return m -> { return range(0, m[0].length).parallel().mapToObj(r -> range(0, m.length).parallel().mapToDouble(c -> m[c][r]).toArray() ).toArray(double[][]::new); }; } private static final Function<double[][], double[][]> forLoopTranspose() { return m -> { final int rows = m.length; final int columns = m[0].length; double[][] transpose = new double[columns][rows]; for (int r = 0; r < rows; r++) for (int c = 0; c < columns; c++) transpose[c][r] = m[r][c]; return transpose; }; } @State(Scope.Benchmark) public static class MatrixContainer { @Param({ "100", "1000", "3000" }) private int matrixSize; private double[][] matrix; @Setup(Level.Iteration) public void setUp() { ThreadLocalRandom random = ThreadLocalRandom.current(); matrix = random.doubles(matrixSize).mapToObj(i -> random.doubles(matrixSize).toArray()).toArray(double[][]::new); } } @Benchmark public double[][] streamTranspose(MatrixContainer c) { return streamTranspose().apply(c.matrix); } @Benchmark public double[][] parallelStreamTranspose(MatrixContainer c) { return parallelStreamTranspose().apply(c.matrix); } @Benchmark public double[][] forLoopTranspose(MatrixContainer c) { return forLoopTranspose().apply(c.matrix); }}

![用于转换double [] []矩阵的紧凑流表达式 用于转换double [] []矩阵的紧凑流表达式](http://www.mshxw.com/aiimages/31/515475.png)
