如何直接在数组上对多维数组的每个对象执行一个方法?

时间:2009-10-08 10:27:40

标签: java arrays

我正在编写一个简单的Java 2D游戏,显示一个网格。 网格(目前)是一个特定游戏单元的简单二维数组:

int height = 10;
int width = 10;
MyObject[][] table = new MyObject[height][width];

通常,我必须在整个表格中执行我的对象的特定方法:

for(int y = 0; y < height; y++) {
    for(int x = 0; x < width; x++) {
        table[y][x].MyMethod();
    }
}

我的细胞有很多方法(计算游戏规则等),只需要用方法的名称(偶尔,带参数)改变就必须编写相同的代码块,这非常令人厌烦。
Java 中是否有一些快捷方式或一些技巧,以允许更容易和更易读的方法:

table.MyMethod();

SomeFactory(table, MyMethod);

我愿意改变我的桌子的设计,比如,把它变成一个类,如果可能的话,使用泛型来允许可重用​​性。我非常清楚存在值(数组的填充方法),但有没有办法让方法成为动态参数?

感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

您需要有一个界面,例如

public interface Action<T> {
    void apply(T item)
}

然后实施Action<MyObject>并将您的循环转换为:

public void applyToAll(Action<MyObject> action) {
    for(int y = 0; y < height; y++) {
        for(int x = 0; x < width; x++) {
            action(table[y][x]);
        }
    }
}

不幸的是,这在Java中并不像在带有委托的C#中那样整洁,但是在我们用Java获得闭包之前,它就是你能得到的最接近的。

您始终可以像这样实现界面:

private static void MY_METHOD_ACTION = new Action<MyObject>() {
    @Override public void apply(MyObject item) {
        myMethod(item);
    }
};

myMethod当然是一个实例方法时,那不是很整洁......对于包含Action<MyObject>的类的每个实例,你需要一个新的myMethod实例,但它很有用对于静态方法。

当然,如果您愿意直接实施Action<MyObject>,这不是问题。

答案 1 :(得分:0)

这很有效,但你必须实现很多代码,因为每个方法需要多行。

我找到了一个更好的解决方案,使用反射:
1)创建一个通用函数,传递方法的名称和参数,作为vararg:

public void actionCall(String methodName, Object... parameters) {

2)为每个参数找到它的类(注意基元类型)
3)使用以下任一方法查找方法:

yourClass.class.getMethod(name, parameterClasses)
yourObject.getClass().getMethod(name, parameterClasses)

4)解析表和每个单元格使用:

method.invoke(myTable[y][x], params)

然后你只需要调用这样的函数,对于每个方法,不需要额外的代码:

actionAll("methodName", paramValue);

它对构造函数(getConstructor)的作用相同 如果有人有想法,你必须得到返回值会变得复杂吗?

答案 2 :(得分:0)

最实用的解决方案是在IDE或编辑器中定义模板,以便可以使用单个键组合插入重复代码。由于Java缺少闭包或委托以及匿名类的详细语法,因此生成的代码甚至可能比“通用”解决方案更短。

此外,(除非你的方法调用需要索引作为参数),你可以使用“增强的for循环”来获得更清晰的语法:

for(MyObject[] row: table) {
    for(MyObject cell : row) {
        cell.MyMethod();
    }
}