[英]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中,您可以使用现有的
IntConsumer
或LongConsumer
功能接口和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.