问题
Let's say I have a multi-dimensional array as a member of a class and a lot of methods, that loop through every element of the array and then operate on it. The code might look like this:
public class Baz {
private Foo[][] fooArray = new Foo[100][100];
public Baz() {
for (int i = 0; i < fooArray.length; i++) {
for (int j = 0; j < fooArray[i].length; j++) {
// Initialize fooArray
}
}
}
public void method1() {
for (int i = 0; i < fooArray.length; i++) {
for (int j = 0; j < fooArray[i].length; j++) {
// Do something with fooArray[i][j]
}
}
}
public void method2() {
for (int i = 0; i < fooArray.length; i++) {
for (int j = 0; j < fooArray[i].length; j++) {
// Do something else with fooArray[i][j]
}
}
}
// and so on
}
Now, since the code for the loop is always the same, only the operation within the loop changes, is there any way the code for looping could be somehow refactored into a seperate method? It would be so nice to be able to do
doInLoop(functionToExecute());
What would be the nearest substitute for doing something like this, if it is even possible?
回答1:
What you are looking for is the Command pattern: define a single-method interface and implement it for each use case as an anonymous class. You'll pass an instance of this interface to a method which does all the boilerplate and calls your method just for the interesting part:
public void forAllMembers(Foo[][] fooArray, Command c) {
for (int i = 0; i < fooArray.length; i++) {
for (int j = 0; j < fooArray[i].length; j++) {
c.execute(fooArray[i][j]);
}
}
}
Or, wait for Java 8, which will introduce Lambdas and will give your problem a first-class solution!
回答2:
You could sth like this:
public void method1(Performer p) {
for (int i = 0; i < fooArray.length; i++) {
for (int j = 0; j < fooArray[i].length; j++) {
p.doIt(fooArray[i][j]);
}
}
}
static interface Performer {
public void doIt(int ij);
}
then implement different performers and pass them to this single method.
This approach is called Command Pattern
回答3:
public Baz() {
for (int i = 0; i < fooArray.length; i++) {
for (int j = 0; j < fooArray[i].length; j++) {
fooArray[i][j] = initArray(/* .. */);
doSomethingWithFooArray(fooArray[i][j] );
doSomethingElseWithFooArray(fooArray[i][j] );
}
}
}
If you would like to create something generic you can use Interface
,
public interface FooItf{
public void doSomethingWithFooArray(int value );
public void doSomethingElseWithFooArray(int value );
public int initArray(/* .. */);
}
and now you can write something:
public looping(FooItf foo) {
for (int i = 0; i < fooArray.length; i++) {
for (int j = 0; j < fooArray[i].length; j++) {
fooArray[i][j] = foo.initArray(/* .. */);
foo.doSomethingWithFooArray(fooArray[i][j] );
foo.doSomethingElseWithFooArray(fooArray[i][j] );
}
}
}
For now you can generate several classes based on FooItf
and implement any internal logic.
来源:https://stackoverflow.com/questions/17973457/reuse-code-for-looping-through-multidimensional-array