我有一个ArrayList <BlockRealMatrix>,每个成员都具有相同的形状,并且想要将每个成员的对应行平均到n行和1列的另一个BlockRealMatrix中,其中n ==#行的任何BlockRealMatrix成员在原始ArrayList中。 从3个循环开始,我设法通过使用流对每个矩阵的行求和来删除一个循环,但是我想尝试摆脱所有循环,并尽可能使用流。谢谢
import org.apache.commons.math3.linear.BlockRealMatrix;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class StreamAdder {
public static void main(String[] args) {
List<BlockRealMatrix> matrixHolder = new ArrayList<>();
matrixHolder.add(new BlockRealMatrix(2, 3));
matrixHolder.add(new BlockRealMatrix(2, 3));
matrixHolder.get(0).setRow(0, new double[]{1, 2, 3});
matrixHolder.get(0).setRow(1, new double[]{4, 5, 6});
matrixHolder.get(1).setRow(0, new double[]{7, 8, 9});
matrixHolder.get(1).setRow(1, new double[]{10, 11, 12});
matrixHolder.stream().forEach(i -> System.out.println(i));
BlockRealMatrix averages = new BlockRealMatrix(matrixHolder.get(0).getRowDimension(), 1);
for (int i = 0; i < averages.getRowDimension(); i++) {
double average = 0;
for (int j = 0; j < matrixHolder.size(); j++) {
average += Arrays.stream(matrixHolder.get(j).getRow(i)).sum();
}
average /= (matrixHolder.size() * matrixHolder.get(0).getColumnDimension());
averages.setEntry(i, 0, average);
average = 0;
}
System.out.println("Averages \n" + averages);
}
}
打印:
BlockRealMatrix{{1.0,2.0,3.0},{4.0,5.0,6.0}}
BlockRealMatrix{{7.0,8.0,9.0},{10.0,11.0,12.0}}
Averages
BlockRealMatrix{{5.0},{8.0}}
答案 0 :(得分:0)
首先,可以通过直接调用matrixHolder.stream().forEach(i -> System.out.println(i));
列表即forEach
上的matrixHolder
方法或使用方法引用matrixHolder.forEach(i -> System.out.println(i));
来进一步改善matrixHolder.forEach(System.out::println);
。 / p>
对于更改 all ,for
循环使用流API进行内部迭代。简而言之,这不是一个好问题,因为它会说“在这里使用流会很好”,因此,与其尝试使用流API来更改所有的for循环,不如尝试将其做一点更具可读性:
for (int j = 0; j < matrixHolder.size(); j++) { ... }
可以更改为增强的for循环,以使其更具可读性。
for (int i = 0; i < averages.getRowDimension(); i++) {
double average = 0;
for (BlockRealMatrix aMatrixHolder : matrixHolder)
average += Arrays.stream(aMatrixHolder.getRow(i)).sum();
average /= (matrixHolder.size() * matrixHolder.get(0).getColumnDimension());
averages.setEntry(i, 0, average);
}
但是,如果您坚持要完全使用流API,那么您可以这样做:
IntStream.range(0, averages.getRowDimension())
.forEach(i -> {
double average = matrixHolder.stream()
.mapToDouble(m -> Arrays.stream(m.getRow(i)).sum())
.sum();
average /= (matrixHolder.size() * matrixHolder.get(0).getColumnDimension());
averages.setEntry(i, 0, average);
});