我有2个fors,在嵌套之后我有一些代码,如果条件在嵌套for中为真,我不想执行。如果我使用break代码将执行,那么(正如我在SCJP中学到的)我使用continue label;
作为外部for。
这是Java的弃用用法吗?老式的?有人建议使用递归或其他东西,但对我来说这是完全正常,简单,最新和完美的方式。
here:
for (bla bla) {
for (bla bla) {
if (whatever) continue here;
}
// some code I don't want to execute if whatever is true
}
由于
编辑:
如果我将我的问题改为:你怎么能在多个嵌套的fors之间“导航”?这种方法是“推荐”的方式吗?因为这就是它在SCJP Book中所说的。如果不是..这是否意味着Katherine Sierra
和Bert Bates
错了?
编辑2:
为什么continue label;
不鼓励?我想要回答OOP或Java的概念或内部工作,可能会出错......
答案 0 :(得分:6)
我会重构以使其更具可读性。
示例:
if (!checkWhatever()) {
// some code I don't want to execute if whatever is true
}
boolean checkWhatever() {
for (bla bla) {
for (bla bla) {
if (whatever) return false;
}
}
return true;
}
答案 1 :(得分:5)
答案是:这取决于。如果您发现自己经常使用continue
,那么可能表明您的代码需要重构。但是,在您给出的场景中,它似乎是一个使用它的好地方。
答案 2 :(得分:3)
我会说它气馁。它仍然具有有效的用途,其中替代品更复杂或更容易出错(即不是改进)
答案 3 :(得分:2)
参考你的编辑2,它总是看起来有点不确定,因为它违反了旧的编程正统而不是OO:'结构化编程'(见http://en.wikipedia.org/wiki/Structured_programming)。它也很棒,所有优秀的程序员都知道如果他们让他们的代码进入他们的代码就需要认罪。
可能会有一些担心,它可能会使编译器更难分析函数的控制流,但它是一种通常因效率原因而被使用的工具。例如,java.lang.String
的Apache实现在此函数中使用它至少是为了优化:
/*
* An implementation of a String.indexOf that is supposed to perform
* substantially better than the default algorithm if the "needle" (the
* subString being searched for) is a constant string.
*
* For example, a JIT, upon encountering a call to String.indexOf(String),
* where the needle is a constant string, may compute the values cache, md2
* and lastChar, and change the call to the following method.
*/
@SuppressWarnings("unused")
private static int indexOf(String haystackString, String needleString,
int cache, int md2, char lastChar) {
char[] haystack = haystackString.value;
int haystackOffset = haystackString.offset;
int haystackLength = haystackString.count;
char[] needle = needleString.value;
int needleOffset = needleString.offset;
int needleLength = needleString.count;
int needleLengthMinus1 = needleLength - 1;
int haystackEnd = haystackOffset + haystackLength;
outer_loop: for (int i = haystackOffset + needleLengthMinus1; i < haystackEnd;) {
if (lastChar == haystack[i]) {
for (int j = 0; j < needleLengthMinus1; ++j) {
if (needle[j + needleOffset] != haystack[i + j
- needleLengthMinus1]) {
int skip = 1;
if ((cache & (1 << haystack[i])) == 0) {
skip += j;
}
i += Math.max(md2, skip);
continue outer_loop;
}
}
return i - needleLengthMinus1 - haystackOffset;
}
if ((cache & (1 << haystack[i])) == 0) {
i += needleLengthMinus1;
}
i++;
}
return -1;
}
答案 4 :(得分:1)
通过将内部循环放在自己的方法中来重构以使其更具可读性:
for (bla bla) {
DoStuff();
}
void DoStuff() {
for (bla bla) {
if (whatever) return;
}
// some code to execute when whatever is false.
}
原则:如果方法变得足够复杂,需要对一个块进行LABELING,请考虑将该方法的一部分重构为一个单独的方法,这样就不需要标签。
同样,制作三个循环的方法是不明智的。除非循环非常简单。即使不需要标签。通过将复杂性隐藏在其他方法中,确保最外面的流构造(循环,或if / else或开关)易于阅读。即使这些方法只从一个地方调用。
答案 5 :(得分:0)
使用名为&#39;成功的布尔值&#39;或类似的东西。 它更容易阅读和遵循流程。 Gotos只应用于错误处理。
boolean success = true;
for(int outer = 0; (outer <= outerLimit) && sucess; outer++)
{
for(int inner = 0; (inner <= innerLimit) && success; inner++)
{
if( !doInnerStuff() )
{
success = false;
}
}
if( success )
{
success = doOuterStuff();
}
}