重用 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