简体   繁体   中英

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.

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.

You say you are not familiar with functional interfaces, so here's an alternative approach using normal classes, which allows you to use Java's for-each loop.

I assumed your matrix values were doubles, but if they aren't then switch out the doubles for whatever type you're using.

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

Sample usage:

double[][] matrix = {{1.1, 2.2}, {3.3, 4.4}};
for (MatrixElement element : matrixIterable(matrix)) {
    System.out.println("(" + element.getX() + ", " + element.getY() + ") " + element.getValue());
}

Prints

(0, 0) 1.1
(1, 0) 3.3
(0, 1) 2.2
(1, 1) 4.4

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM