简体   繁体   English

Java - 避免矩阵迭代中的代码重复

[英]Java - avoiding code duplication in matrix iteration

Suppose I have an int[size][size] matrix. 假设我有一个int [size] [size]矩阵。 I want to iterate through it like so: 我想像这样迭代它:

01 02 03 04
08 07 06 05
09 10 11 12
16 15 14 13

Do I really have to say: 我真的不得不说:

for (int y=0; y<size; y++) {
    int startIndex, endIndex, increment;
    boolean lessThan;
    if (y%2 == 0) {
        startIndex = 0;
        endIndex = size;
        lessThan = true;
        increment = 1;
    }
    else {
        startIndex = size-1;
        endIndex = -1;
        lessThan = false;
        increment = -1;
    }
    for (int x=startIndex; lessThan ? x<endIndex : x>endIndex; x+=increment) {
        // Process element
    }
}

to avoid doing this: 避免这样做:

for (int y=0; y<size; y++) {
    if (y%2 == 0) {
        for (int x=0; x<size; x++) {
            // Process element
        }
    }
    else {
        for (int x=size-1; x>-1; x--) {
            // Process element
        }
    }
}

which is far nicer but repeats code. 哪个更好,但重复代码。 Is there a better way to structure this? 有没有更好的方法来构建它?

Create an interface to abstract the logic of processing the element: 创建一个interface来抽象处理元素的逻辑:

interface ElementConsumer {
    void consume(int element);
}

Then use this abstraction in the loop: 然后在循环中使用这个抽象:

void iterateMatrix(final int[][] matrix, final ElementConsumer consumer) {
    for (int y = 0; y < size; y++) {
        if (y % 2 == 0) {
            for (int x = 0; x < size; x++) {
                consumer.consume(matrix[x][y]);
            }
        } else {
            for (int x = size - 1; x > -1; x--) {
                consumer.consume(matrix[x][y]);
            }
        }
    }
}

Use the method thus: 使用这种方法:

iterateMatrix(matrix, new ElementConsumer() {
    @Override
    public void consume(int element) {
        //do stuff
    }
});

In Java 8 you can use the existing IntConsumer or LongConsumer functional interfaces and a lambda: 在Java 8中,您可以使用现有的IntConsumerLongConsumer功能接口和lambda:

iterateMatrix(matrix, element -> /*doStuff*/);

One more approach to iterate through matrix: 另一种迭代矩阵的方法:

for (int num = 0; num < maxX*maxY; ++num) { // num - element number
    // calc element coordinates
    int y = num / maxX;
    int x = num % maxX;
    if (y % 2 == 1)
       x = maxX - x;
    int elem = matrix[x][y];
    // process element
}

Can be accomplished this way too.. 也可以这样完成..

package com.kvvssut.misc;

public class TraverseAlternately {

    public static void main(String[] args) {
        traverseAlternately(new int[][]{{1,2,3,4},{8,7,6,5},{9,10,11,12},{16,15,14,13}});
    }

    private static void traverseAlternately(int[][] inputs) {
        int rows = inputs.length;
        if (rows > 0) {
            int i = -1;
            int j = 0;

            int cols = inputs[j].length;        // assuming all rows have same no.s of values

            while (true) {
                while (++i < cols) {        // traverses till the end of first row
                    System.out.println(inputs[j][i]);
                }
                if (j < rows - 1) {     // if reaches the no.s of rows, loop breaks
                    j++;
                } else {
                    break;
                }

                while (--i >= 0) {          // traverses backward to the zeroth location
                    System.out.println(inputs[j][i]);
                }
                if (j < rows - 1) {     // if reaches the no.s of rows, loop breaks
                    j++;
                } else {
                    break;
                }
            }
        }
    }

}
for (int y = 0; y < size; y++) {
    for (int x = (y%2 == 0 ? 0 : size - 1);
            (y%2 == 0 ? x < size : x >= 0);
            (y%2 == 0 ? x++ : x--)) {
        // Process element
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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