Java 如何在循环体中写入条件?

Java 如何在循环体中写入条件?,java,c++,coding-style,Java,C++,Coding Style,这可能有点主观,但事实上我正在寻找包含一些推理的答案 对于循环体中的条件,我遇到了以下两种编程风格。这: for (int i = 0; i < myArray.length; i++) { if (myArray[i].isEmpty()) continue; doSomeStuff(); doSomeMoreStuff(); } 这是我将每一行读入name对象的方式,忽略空行(可能发生): 到目前为止,我更喜欢第二个,因为我发现它在语义上更容

这可能有点主观,但事实上我正在寻找包含一些推理的答案

对于循环体中的条件,我遇到了以下两种编程风格。这:

for (int i = 0; i < myArray.length; i++) {
    if (myArray[i].isEmpty())
        continue;

    doSomeStuff();
    doSomeMoreStuff();
}
这是我将每一行读入name对象的方式,忽略空行(可能发生):


到目前为止,我更喜欢第二个,因为我发现它在语义上更容易阅读。
这使得重构更容易。

对我来说,这取决于循环的内容

如果循环最多只包含5行和一个条件,我通常会使用第二种样式,因为我发现它更容易看到代码何时执行


如果有很多嵌套条件(没有
else
),我更喜欢第一种语法,原因与您大致相同:防止大缩进。当使用第二种样式时,每个后续条件检查都会不必要地增加缩进级别,降低可读性。

继续、转到、中断是我们认为不应该使用的第一个单词。若方法再长一点,你们会发现这是个坏主意。 第二个教训是尽可能使用积极的条件:)

免责声明:本文中的答案仅反映了回答者的想法,不应被视为普遍共识

对我来说,这是关于可读性的。尽管我能理解这两个循环体,但有些人可能会花时间理解它们

第二个循环体仅在数组中的元素不为空时执行,而第一个循环体发现数组中的元素为空并通知for循环继续


第二个循环的可读性也使有意识的调试变得容易,就好像它告诉人们,如果调用
doSomeStuff()
doSomeMoreStuff()
,元素永远不能为空一样。

第二个更好。编程时尽量避免使用continue、break和goto(?)。它们只是拐杖。

这在很大程度上取决于实际代码的外观;如果它在本质上更为连续,我更喜欢初始的
continue
,如果满足条件,如果它仍然是分支,我使用分支跳过迭代;但是,如果嵌套的级别变深,我可能会使用
continue
anway。。。如果您想要一种样式,并且每次循环都使用这种样式,那么我建议使用第二种版本(分支),但是,因为这种样式的情景性不如
continue
那么它通常取决于条件。我尽量避免否定条件,尤其是更复杂的条件。因此,我经常以第一种风格出现。在一开始就对特殊情况进行分类并不是一件坏事,这样就可以一次编写一般情况下的算法。

< p>我使用<代码>继续<代码>(或有时在代码的中间<代码> >破译<代码>或<代码> Goto ,但总是把它放在一行上。(因此,
continue
不能意外地与
if
分开),并始终以“if…,we's done”的形式提供注释


注释是一个强大的工具。十个缩进级别确实比这里或那里的
goto
更难阅读。一些控制流结构不会记录它们自己。

第二个。如果有很多缩进级别,可以通过将块转换为单独的方法来重构。

怎么样:

for (int i = 0; i < myArray.length; i++) {
    doStuffToValue(myArray[i]);    
}

void doStuffToValue(String value) {
    if (value.isEmpty()) {
        return;
    } 
    doSomeStuff();
    doSomeMoreStuff();
}
for(int i=0;i

通过这种方式,您可以检查值的有效性,而不是循环体。如果需要,您甚至可以为dostufftovue方法编写单元测试。

事实上,第二个值会增加,并可能导致错误


此外,保留所有“代码不应通过此点”开始时的检查允许您将它们组合在一起,这意味着它们更容易维护imho。

只需重构。原因是,如果MyObject为空,则它可以自己进行内部调用。没有理由让其他人询问MyObject是否为空,只是为了让MyObject执行某些操作。这是属于MyObject的逻辑例如,您希望尽可能多地将逻辑放在对象内部,以便其他潜在调用方可以重用它,但如果可以避免的话,系统的其他部分也不会调用他们不拥有的东西

for(MyObject object : list) {
    object.doABunchOfSimilarThings();
}

....

class MyObject {

    ...

    public void doABunchOfSimilarThings() {
        if(notEmpty()) {
            doThing1();
            doThing2();
            doThing3();        
        }
    }

    ...

}

我认为我从来没有在循环中使用过
continue
,尽管我在函数开头经常使用第一个习惯用法
return
因此,
if
倾向于与代码的其他部分更加一致

一个不那么主观的原因是,如果您经常跳过整个循环迭代,通常会有一种方法来重构在循环之外做出的决策,这会对性能产生影响。例如,我更喜欢使用永远不会有空值的数据结构

对于性能不是问题的不可避免的复杂事物,我倾向于使用Adrian的方法将循环体分解为函数


在这三个原因中,
continue
在语法上是可能的,最容易阅读,与使用该数据结构的其他代码一致,而且最高效的解决方案出现的频率不足以证明其使用的合理性。

第一种样式,原因与您相同。仅在 继续
。我认为这更符合个人偏好。但我认为第一个更容易阅读。如果有很多嵌套条件等,那么函数太长太复杂,需要重构。我更喜欢
while (line = file.readLine()) {
    if (line.isEmpty())
        continue;

    String[] columns = line.split(";");
    names.add(new Name(columns[0], columns[1]));
}
for (int i = 0; i < myArray.length; i++) {
    doStuffToValue(myArray[i]);    
}

void doStuffToValue(String value) {
    if (value.isEmpty()) {
        return;
    } 
    doSomeStuff();
    doSomeMoreStuff();
}
for(MyObject object : list) {
    object.doABunchOfSimilarThings();
}

....

class MyObject {

    ...

    public void doABunchOfSimilarThings() {
        if(notEmpty()) {
            doThing1();
            doThing2();
            doThing3();        
        }
    }

    ...

}