重用 for 循环的最佳方法是什么?
What is the best way to reuse a for-loop?
我目前正在研究一个矩阵 class,它(将)允许您对其执行操作。但是,因为我使用二维数组来表示 class 内的矩阵,所以我经常发现自己使用以下循环(对所有元素执行某些操作):
for (int y = 0; y < this.matrix.length; y++) {
for (int x = 0; x < this.matrix[0].length; x++) {
// do something
}
}
重用此循环但让它在循环内执行不同代码段的好方法是什么?
我考虑过功能接口,但还没有完全弄明白。
如果你在方法中有这个
void iterateMatrix(int[][] matrix) {
for (int y = 0; y < matrix.length; y++) {
for (int x = 0; x < matrix[0].length; x++) {
// do something
}
}
}
你可以为“做某事”定义一个功能接口
interface MatrixVisitor {
void accept(int x, int y, int value);
}
它是一个“功能接口”,因为它只包含一个方法;你可以用@FunctionInterface
来标记它,但这只是一个标记,不是必需的。
您可以通过
使用它
void iterateMatrix(int[][] matrix, MatrixVisitor consumer) {
for (int y = 0; y < matrix.length; y++) {
for (int x = 0; x < matrix[0].length; x++) {
consumer.accept(x, y, matrix[x][y]);
}
}
}
它作为函数式接口的效果是您可以使用 lambda 来“实现”它,例如
iterateMatrix(this.matrix, (x, y, value) -> System.out.printf("value at %d/%d: %d%n", x, y, value));
问题仍然是这是否是“最佳方式”,这是一个相当微不足道的循环,所以我不知道重用它是否值得。
你说你不熟悉函数式接口,所以这里有一个使用普通 类 的替代方法,它允许你使用 Java 的 for-each 循环。
我假设您的矩阵值是双精度值,但如果不是,则将双精度值切换为您正在使用的任何类型。
static class MatrixElement {
private final int x;
private final int y;
private final double value;
// ctor, getters
}
static Iterable<MatrixElement> matrixIterable(double[][] matrix) {
final List<MatrixElement> elements = new ArrayList<>();
for (int y = 0; y < matrix.length; y++) {
for (int x = 0; x < matrix[y].length; x++) {
elements.add(new MatrixElement(x, y, matrix[x][y]));
}
}
return elements;
}
示例用法:
double[][] matrix = {{1.1, 2.2}, {3.3, 4.4}};
for (MatrixElement element : matrixIterable(matrix)) {
System.out.println("(" + element.getX() + ", " + element.getY() + ") " + element.getValue());
}
版画
(0, 0) 1.1
(1, 0) 3.3
(0, 1) 2.2
(1, 1) 4.4
我目前正在研究一个矩阵 class,它(将)允许您对其执行操作。但是,因为我使用二维数组来表示 class 内的矩阵,所以我经常发现自己使用以下循环(对所有元素执行某些操作):
for (int y = 0; y < this.matrix.length; y++) {
for (int x = 0; x < this.matrix[0].length; x++) {
// do something
}
}
重用此循环但让它在循环内执行不同代码段的好方法是什么?
我考虑过功能接口,但还没有完全弄明白。
如果你在方法中有这个
void iterateMatrix(int[][] matrix) {
for (int y = 0; y < matrix.length; y++) {
for (int x = 0; x < matrix[0].length; x++) {
// do something
}
}
}
你可以为“做某事”定义一个功能接口
interface MatrixVisitor {
void accept(int x, int y, int value);
}
它是一个“功能接口”,因为它只包含一个方法;你可以用@FunctionInterface
来标记它,但这只是一个标记,不是必需的。
您可以通过
使用它void iterateMatrix(int[][] matrix, MatrixVisitor consumer) {
for (int y = 0; y < matrix.length; y++) {
for (int x = 0; x < matrix[0].length; x++) {
consumer.accept(x, y, matrix[x][y]);
}
}
}
它作为函数式接口的效果是您可以使用 lambda 来“实现”它,例如
iterateMatrix(this.matrix, (x, y, value) -> System.out.printf("value at %d/%d: %d%n", x, y, value));
问题仍然是这是否是“最佳方式”,这是一个相当微不足道的循环,所以我不知道重用它是否值得。
你说你不熟悉函数式接口,所以这里有一个使用普通 类 的替代方法,它允许你使用 Java 的 for-each 循环。
我假设您的矩阵值是双精度值,但如果不是,则将双精度值切换为您正在使用的任何类型。
static class MatrixElement {
private final int x;
private final int y;
private final double value;
// ctor, getters
}
static Iterable<MatrixElement> matrixIterable(double[][] matrix) {
final List<MatrixElement> elements = new ArrayList<>();
for (int y = 0; y < matrix.length; y++) {
for (int x = 0; x < matrix[y].length; x++) {
elements.add(new MatrixElement(x, y, matrix[x][y]));
}
}
return elements;
}
示例用法:
double[][] matrix = {{1.1, 2.2}, {3.3, 4.4}};
for (MatrixElement element : matrixIterable(matrix)) {
System.out.println("(" + element.getX() + ", " + element.getY() + ") " + element.getValue());
}
版画
(0, 0) 1.1
(1, 0) 3.3
(0, 1) 2.2
(1, 1) 4.4