Search code examples
javafor-loopfunctional-interface

What is the best way to reuse a for-loop?


I am currently working on a Matrix class that (will) allow you to perform operations on it. However, because I am using a 2D array to represent the matrix inside the class, I've often found myself using the following loop (to do something with all elements):

    for (int y = 0; y < this.matrix.length; y++) {
        for (int x = 0; x < this.matrix[0].length; x++) {
            // do something
        }
    }

What is a good way to reuse this loop, yet have it perform a different piece of code inside the loop?

I've thought about the functional Interfaces, but haven't quite figured those out.


Solution

  • If you have this in a method

    void iterateMatrix(int[][] matrix) {
        for (int y = 0; y < matrix.length; y++) {
            for (int x = 0; x < matrix[0].length; x++) {
                // do something
            }
        }
    }
    

    you can define a functional interface for the "do something"

    interface MatrixVisitor {
        void accept(int x, int y, int value);
    }
    

    It's a "functional interface" because it only contains one method; you can mark it with @FunctionInterface, but that's only a marker and not necessary.

    You can use this via

    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]);
            }
        }
    }
    

    The effect of it being a functional interface is that you can "implement" it using a lambda, like

    iterateMatrix(this.matrix, (x, y, value) -> System.out.printf("value at %d/%d: %d%n", x, y, value));
    

    The question remains whether this is the "best way", it's a rather trivial loop so I don't know if reusing it is worth it.