java - 将额外代码插入 Java for 循环

标签 java for-loop foreach conditional-statements code-duplication

我有一批 Sprite (带纹理的 OpenGL ES 2.0 四边形),我循环移动它们。这是我的代码的简化版本:

//'sprite' & other values have been are assumed to exist for the purpose of the question

public void moveQuadBatch(){

    //Loop for as many sprites as there are to draw
    for (loop = 0; loop < sprite.number; loop++){

        moveQuadNumber(loop); //this method will move the sprite that corresponds to the number loops so we can move through the entire batch and move each individual sprite


    }
}

现在,对于某些批处理,有一个倒计时计时器或其他一些条件(而对于其他批处理则没有,如上)。因此,我为这些对象创建了一个类似的方法,如下所示:

public void moveQuadBatchWithCheck(){

    //Loop for as many sprites as there are to draw
    for (loop = 0; loop < sprite.number; loop++){

        //Only do this if the particular sprite's countdown/delay counter has reached 0 (counting down from another method not seen here)
        if (sprite.delay[loop]<0){

            moveQuadNumber(loop); //this method will move the sprite that corresponds to the number loops so we can move through the entire batch and move each individual sprite

        }
    }
}

但是,我对此并不完全满意,因为有很多代码重复。除了使用这两种方法之外,还有什么方法可以使用第一种方法并以某种方式“滑流”额外检查 for 循环?或者以其他方式减少我在这里的重复?这是一个简单的示例,还有其他示例,目前我有多种方法都非常相似。

编辑

如前所述,上面的内容有些简化。我可以有一些 for 循环来检查另一个值(例如延迟除外),有些可以检查 2 个条件。

最佳答案

public void moveQuadBatch(bool checkDelay) {
    for (loop = 0; loop < sprite.number; loop++){
        if (!checkDelay || sprite.delay[loop] < 0) {
             moveQuadNumber(loop);
        }
    }
}

现在 moveQuadBatch(false) 是您的第一个函数,moveQuadBatch(true) 是您的第二个函数。


至于“插入额外代码”,你基本上是在谈论函数。在 Python 中,一种优雅的方法是传入一个函数并将所有逻辑卸载给该函数,例如:

    def moveQuadBatch(predicate=None):
        for loop, sprite in enumerate(self.sprites): 
            if not predicate or predicate(loop, sprite):
                self.moveQuadNumber(loop)

然后你可以这样使用它:

inst.moveQuadBatch()  
inst.moveQuadBatch(lambda loop, sprite: sprite.delay[loop] < 0)
inst.moveQuadBatch(lambda loop, sprite: sprite.doesItBlend(loop))

您可以在 Java 中做同样的事情,但不是那么巧妙:您必须定义谓词类及其实例。这就是 B.J. Smegma 提倡的方法。

public interface QuadBatchPredicate {
    public boolean shouldMove(int loop, Sprite sprite);
}

你的函数看起来像这样:

public void moveQuadBatch(QuadBatchPredicate pred) {
    for (loop = 0; loop < sprite.number; loop++){
        if (pred == null || pred(loop, sprite)) {
             moveQuadNumber(loop);
        }
    }
}
public void moveQuadBatch() {
    moveQuadBatch(null);
}

然后你可以使用匿名类来定义谓词:

moveQuadBatch();
moveQuadBatch(new QuadBatchPredicate() {
    public boolean shouldMove(int loop, Sprite sprite) {
        return sprite.delay[loop] < 0;
    }
});
moveQuadBatch(new QuadBatchPredicate() {
    public boolean shouldMove(int loop, Sprite sprite) {
        return sprite.doesItBlend();
    }
});

比 Python 解决方案有点粗糙,但它明白了要点。现在,您可以通过将谓词在线定义为您想要的任何内容,将代码“插入”到函数中。另外,您可以保存常用的,这样您就不会在各处重复它们:

QuadBatchPredicate checkBlends = new QuadBatchPredicate() {
    public boolean shouldMove(int loop, Sprite sprite) {
        return sprite.doesItBlend();
    }
};

关于java - 将额外代码插入 Java for 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21792491/

相关文章:

c# - 跳出嵌套循环

javascript - 我可以使用循环来优化我的代码吗?

r - 将 for 循环的结果存储在对象或矩阵中

java - 通过序列化和反序列化在 mqtt 中发送和接收对象会导致 classnotfound 异常

java - 有没有什么好的工具可以用来查找 GUI、分解的 Pane 和组件的使用统计信息?

reactjs - 如何在 Reactjs 中一次调用上传多个图像文件

r - 在 R 中嵌套并行函数 (

c# - 如何在linq中使用foreach

java - Feign 无法解析名称

java - 在 set 方法中抛出的最佳异常