Java for循环的括号中可以有什么内容?

时间:2009-06-18 19:18:51

标签: java syntax for-loop

我的问题是关于Java for语句,例如

for (int i = 0; i < 10; ++i) {/* stuff */}

我不明白的是,我可以在括号中添加多少代码/代码类型(即我的示例中有int i = 0; i < 10; ++i的地方) - 我真的不明白以前使用的语言在此描述:

http://java.sun.com/docs/books/jls/third_edition/html/statements.html#24588

基本上我的问题归结为要求翻译规范中的位:

ForInit: StatementExpressionList LocalVariableDeclaration

编辑:哇。我想真正的答案是“学会阅读并理解JLS中使用的符号 - 它被用于某种原因”。谢谢你的所有答案。

13 个答案:

答案 0 :(得分:17)

StatementExpressionListLocalVariableDeclaration都在页面的其他位置定义。我会在这里复制它们:

StatementExpressionList:
        StatementExpression
        StatementExpressionList , StatementExpression

StatementExpression:
        Assignment
        PreIncrementExpression
        PreDecrementExpression
        PostIncrementExpression
        PostDecrementExpression
        MethodInvocation
        ClassInstanceCreationExpression

LocalVariableDeclaration:
        VariableModifiers Type VariableDeclarators

VariableDeclarators:
        VariableDeclarator
        VariableDeclarators , VariableDeclarator

VariableDeclarator:
        VariableDeclaratorId
        VariableDeclaratorId = VariableInitializer

VariableDeclaratorId:
        Identifier
        VariableDeclaratorId [ ]

VariableInitializer:
        Expression
        ArrayInitializer

进一步遵循语法没有多大意义;我希望这很容易阅读。

这意味着您可以<{>> 任意数量的StatementExpressions,以逗号分隔, LocalVariableDeclaration ForInit 1}}部分。 LocalVariableDeclaration可以包含任意数量的“variable = value”对,以逗号分隔,并以其类型开头。

所以这是合法的:

for (int i = 0, j = 0, k = 0;;) { }

因为“int i = 0, j = 0, k = 0”是有效的LocalVariableDeclaration。这是合法的:

int i = 0;
String str = "Hello";
for (str = "hi", i++, ++i, sayHello(), new MyClass();;) { }

因为初始化程序中的所有随机内容都符合StatementExpressions

由于for循环的更新部分允许StatementExpressionList,因此也是有效的:

int i = 0;
String str = "Hello";
for (;;str = "hi", i++, ++i, sayHello(), new MyClass()) { }

你是否开始了解情况?

答案 1 :(得分:7)

请注意:我们希望在括号中看到非常简单,非常熟悉的内容。超越

for (int i = 0; i < n; i++)

很可能会混淆未来的代码读者。有时你需要以相反的顺序迭代 - 即使起始和结束条件也会给许多程序员带来麻烦(是n,n-1,n + 1?是&gt; 0,&gt; = 0,......?)< / p>

的情况需要详细说明。我只是说 - 在你去那儿之前要小心,考虑更简单的陈述。

答案 2 :(得分:3)

基本上,对于一个简单的FOR循环:

for (startCondition; endCondition; increment)
在startCondition中

,设置用于运行循环的变量的起始值;在许多情况下,您会将其视为 i

int i = 0

在endCondition中,指定循环继续进行的比较。所以,如果你想在i = 15时停止循环,你可以放

i <= 15

OR

i != 15

您还可以执行与布尔值比较等操作,例如

i == true

以递增方式指定计数器变量在每次循环后应递增多少。如果你想简单地增加1,你可以放

i++

你可以在startCondition和endCondition以及多个计数器中使用更多表达式,但是这是一个简单的FOR循环。

答案 3 :(得分:3)

<强> StatementExpressionList

意味着您可以:

int x = 0; 
int y = 0;
int z = 0;


for ( x++, y++; x+ y < z; z++) {
// whatever
}

其中x ++,y ++是表达式列表的列表。基本上你想要在循环开始时执行的语句。

LocalVariableDeclaration 看起来像

int j = 0, i = 0, k = 0;

所以

for ( int j = 0, i = 0, k = 0; i+j+k < 10; i++, j++, k++ ){
// whatever
}

答案 4 :(得分:2)

for循环中的第二个语句(条件)可以是任何计算为布尔值或布尔值的语句。通常情况下,这类似于i < max,但也可能是hasMore()(x > y) == boolmyclient.getMapOfIntsToBools().get(i)之类的内容。只要表达式的结果是布尔值,它就不会有多长。

其他两个部分基本上可以是任何单个语句:无论它的最终返回类型是什么,它都被忽略(就像它在空行上一样)。第一个语句总是在第一个循环开始时精确执行一次,而另一个语句在每个循环结束时执行。

另一种思考方式是:

if (A; B; C){
  ...
}

变成了这个:

A
while (B){
  ...
  C
}

A和C可以是您想要的任何单个语句(包括任何内容)。 B 必须是评估为布尔值的东西。

答案 5 :(得分:1)

你可以把

for(stmt a,stmt b, stmt,c.... ; stmt 1; alpha, beta, omega,...){}

其中stmt:statement;

a,b,c等可以

定义局部变量或其他陈述

for(int a=0,b=0;;){}

将声明并初始化a和b为0;

for(a=i,b=a+1;;){}

将a和b分配给这些值

使用迭代器,你可以

 for(Iterator it= my_list.iterator();;){}

1,2,3等必须返回布尔值,

所以你不能把像

这样的东西
 for (;a++;)

但你可以

for (;a<b;)

for(;it.hasNext();)

基本上是一个while循环。

或者根本没有:)

 for(int a=0;;a++)

对于alpha,omega ..部分,应使用分配运算符

for(;;a){} 

不会编译,但

for(;;a++){}
for(;;a=b;a++){}

意愿。

然后你有 foreach构造,这更简单

for (A a:getAList())

并遍历整个列表,包含当前元素。不需要控制变量。

答案 6 :(得分:1)

  

BasicForStatement:           for(ForInitopt; Expressionopt; ForUpdateopt)   声明

for语句由ForInit,Expression和ForUpdate组成,每个都是可选的

  

ForInit:           StatementExpressionList           LocalVariableDeclaration   forInit是用逗号分隔的语句和表达式列表(见下文)或局部变量的声明

     

ForUpdate:           StatementExpressionList

forUpdate是用逗号分隔的语句和表达式列表...基本上,你可以放:         分配
        PreIncrementExpression         PreDecrementExpression         PostIncrementExpression         PostDecrementExpression         的MethodInvocation         ClassInstanceCreationExpression

  

StatementExpressionList:           StatementExpression           StatementExpressionList,StatementExpression

什么是声明:

  
    

程序的执行顺序由语句控制,     为了它们的效果而被执行     并且没有价值观。

  
     

有些陈述包含其他陈述   陈述作为其结构的一部分;   这样的其他陈述是   声明的子语句。我们说   该声明S立即包含   声明U如果没有声明T   与S和U不同,S   包含T和T包含U.在   同样的方式,一些陈述包含   表达作为他们的一部分   结构

表达式是

  

程序中的大部分工作都是通过计算表达式来完成的,无论是因为它们的副作用,例如变量的赋值,还是它们的值,它们可以在较大的表达式中用作参数或操作数,或者影响执行语句中的序列,或两者兼而有之。

所以基本上你可以在中间有任何有效的java表达式(你不需要比较)但是这个表达式仍然必须返回一个布尔值......

答案 7 :(得分:0)

for(startCondition(s); endCondition(s); Action) {}

只要startCondition(s)和endCondition(s)被评估为布尔值(真或假,1或0取决于语言),您可以根据需要将“条件”列为“长”。

答案 8 :(得分:0)

你可以有很多陈述;然后是在每个周期进行评估的单个条件,最后是另一组语句

答案 9 :(得分:0)

使用循环翻译规范

for (initFor; endCondition; update)

startCondition是一个语句列表,其值被丢弃(不包括任何语句)。他们指定LocalVariableDeclaration注意如果局部变量声明在语句中(例如int x = 0),则局部变量被“作用域”到for语句的块(即该值将不可用在街区或for语句之外)。

endCondition是一个布尔表达式。同样,它是可选的(如果没有循环继续)

update是一个语句列表,通常用于处理每个循环后所需的更新。

答案 10 :(得分:0)

您收到的回复很多,并没有真正回答您的问题。正确答案是你可以放任何你想要的东西。如果for循环中包含break语句,则甚至不需要有效的结束条件。在使用Iterator循环的情况下,您也不需要三个语句。

编辑:好的,不太对劲。您无法在第一个分号后初始化新变量。

答案 11 :(得分:0)

for循环的所有三个子句都是可选的,但分号必须在那里。

在for循环的第一个子句中,您可以用逗号分隔任意数量的语句。或者,在替代方案中(但您不能混合),您可以声明可用于for循环的单个类型的新变量(例如,int i = 1,j = 2)。这里声明的任何变量都可以在for循环之后的语句中使用(或者如果使用花括号则使用语句)。

for循环的第二个子句是返回布尔值的单个语句。将对此进行评估,以考虑for循环是否应继续。

for循环的第三个子句可以包含由逗号分隔的任意数量的语句,但不能声明任何变量。

答案 12 :(得分:0)

您可能会发现每个符号通常更简单,更清晰。我建议在适当的时候使用for循环。 e.g。

for(Element element: arrayOfElement) { /* stuff */ }
// or
for(Element element: iterableOfElement) { /* stuff */ }

Collection,Set和List是Iterable,但你可以创建自己的。