ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java-逻辑内部循环?还是两个独立的几乎完全相同的循环?

2019-10-26 14:03:19  阅读:185  来源: 互联网

标签:convention loops if-statement java


注意:我的印象是您要避免循环内的逻辑语句.我之所以这么说是部分原因是因为编译器如何优化迭代可预测的任何循环.虽然我几乎可以肯定,但我早已听说过这一点,并且很长一段时间以来,我都将其视为惯例.可悲的是我找不到任何好的参考资料.但是,如果这是真的,则由于“ DRY”原理而导致一些冲突的情况(不要重复自己).

前提:假设您有相当大的数据集,请像我在本示例中使用的那样说一个多维数组.此外,假设您需要遍历每个条目并对所有或某些元素执行某些操作,并且需要能够选择要执行一项或另一项操作.这要求创建两个方法,其中90%-99%的代码在两者之间是相同的,而仅运算符或方法调用是不同的.如果这是C语言,我希望提供一个指向循环函数的函数指针,尽管我不知道是否也希望避免这种情况.

问题:使用逻辑语句并仅具有一个循环或两个几乎完全相同的方法会是更可取的吗?

示例:我提供了一些示例来展示“ twin”方法解决方案看起来有多冗余:

// This method is provided for completeness of the example
// and to provide some clue as to what boolean parameter and logic statement 
// I could alternatively have implemented within the loop method instead of external to it.
public int[][] addOrSubtractArrays(int[][] a, int[][] b, boolean useAdd){
    if(a == null || b == null || a.length != b.length || a.length < 1 || a[0].length != b.length)
        return null;
    return useAdd ? add(a, b) : subtract(a, b);
}

private int[][] add(int[][] a, int[][] b){
    int h = a.length;
    int w = a[0].length;
    int[][] c = new int[h][w];
    for(int y = 0; y < h; y++){
        for(int x = 0; x < w; x++){
            c[y][x] = a[y][x] + b[y][x];
        }
    }
    return c;
}

private int[][] subtract(int[][] a, int[][] b){
    int h = a.length;
    int w = a[0].length;
    int[][] c = new int[h][w];
    for(int y = 0; y < h; y++){
        for(int x = 0; x < w; x++){
            c[y][x] = a[y][x] - b[y][x];
        }
    }
    return c;
}

示例2 :(显而易见的?)替代方法

private int[][] addOrSubtract(int[][] a, int[][] b, boolean useAdd){
    if(a == null || b == null || a.length != b.length || a.length < 1 || a[0].length != b.length)
        return null;
    int h = a.length;
    int w = a[0].length;
    int[][] c = new int[h][w];
    for(int y = 0; y < h; y++){
        for(int x = 0; x < w; x++){
            if(useAdd)
                c[y][x] = a[y][x] + b[y][x];
            else
                c[y][x] = a[y][x] - b[y][x];
        }
    }
    return c;
}

我过于想采用某种通用方法来保持整个循环结构,以避免(几乎)重复代码.但是,如果“我所听到的”具有合理的上下文,就我所知,最好避免这种情况.

解决方法:

addOrSubtract不好.其他算术形式(例如乘法)又如何呢?您可以公开一个multipleOrDivide,但是如果应该选择addOrMultiply的时候到了怎么办?伸缩性不好.

您应该拥有的是一种方法,该方法允许客户端指定要执行的操作:

public int[][] calculate(int[][] first, int[][] second, Operation operation) {
    if(firstArray == null || secondArray == null || firstArray.length != secondArray.length || firstArray.length < 1 || firstArray[0].length != secondArray.length)
        throw new IllegalArgumentException("Arrays can't be null and must be of equal length.");

    int height = firstArray.length;
    int width = firstArray[0].length;
    int[][] result = new int[height][width];
    for(int y = 0; y < height; y++){
        for(int x = 0; x < width; x++){
            result[y][x] = operation.performOn(firstArray[y][x], secondArray[y][x]);
        }
    }
}

现在,您可以根据需要添加新的操作:

enum Operation {
    ADD {
        @Override
        public void performOn(int firstValue, int secondValue) {
            return firstValue + secondValue;
        }
    },
    SUBTRACT {
        //...
    };

    public abstract int performOn(int firstValue, int secondValue);
}

如果您觉得以这种方式进行覆盖会使扩展变得过于冗长,则可以通过将逻辑委托给回调函数来使用策略模式:

enum Operation { //could/should implement IOperation
    ADD((a, b) -> a + b),
    SUBTRACT((a, b) -> a - b);

    private IOperation operation;

    Operation(IOperation operation) {
        this.operation = operation;
    }

    public final int performOn(int firstValue, int secondValue) {
        return operation.performOn(firstValue, secondValue);
    }
}

interface IOperation {
    int performOn(int firstValue, int secondValue);
}

客户端现在可以使用您的功能,如下所示:

calculate(firstArray, secondArray, Operation.ADD);

我选择创建新的功能接口而不是使用BiFunction的原因是为了避免自动装箱.性能似乎是您的后顾之忧,而自动装箱会极大地影响性能,特别是如果您将强烈地执行此操作.无论是来自大型数组,还是需要在短时间内连续调用addOrSubtract,都最好避免陷阱.

IllegalArgumentException允许程序用描述性消息“炸毁”.您返回了null,这意味着使用此方法的任何人都需要执行null检查(有些杂物,代码气味,billion dollar mistake),否则他们可能会遇到没有描述性消息的NullPointerException.

标签:convention,loops,if-statement,java
来源: https://codeday.me/bug/20191026/1936945.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有