为什么这个循环不好练习?

use*_*340 20 java loops coding-style

以下循环不是好习惯.它是由于Stringfor循环的主要条件而不是int变量,这意味着for循环是无限的吗?另外,是否因为没有实例进入'结束'来停止循环?

Scanner in = new Scanner(System.in);
int i = 0;
for (String s = in.next(); !s.equals("end"); i++) 
{
    System.out.println("The value of i is: " + i + " and you entered " + s);
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能重写它,以便它符合公认的风格?

(这是过去的试卷中的一个问题.)

ars*_*jii 39

那么你的字符串s永远不会改变,这会导致无限循环.你可能想要:

for (String s = in.next(); !s.equals("end"); s = in.next(), i++) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

有些人(包括我)可能会说不i++应该在这个循环的增量部分,因为它与条件没有直接关系:

for (String s = in.next(); !s.equals("end"); s = in.next()) {
    ...
    i++;
}
Run Code Online (Sandbox Code Playgroud)

是因为字符串是for循环的主要条件而不是int变量,这意味着for循环是无限的?

原始循环确实是无限的(至少在输入初始输入并假设"end"不是第一个输入之后).但是,这并不是你说的原因.for循环采用积分循环控制变量最常写的,但它并不总是如此.例如,迭代链表的常用习语是:

for (Node node = list.head; node != null; node = node.next) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

你的循环的问题是字符串s永远不会改变,所以它永远不会相等,"end"除非这是第一个输入.

  • 马可:也取消了可读性...... (7认同)
  • `for(String s;!(s = in.next()).equals("end");)`消除重复. (2认同)

and*_*ler 34

我建议将循环条件和调用分开Scannner.next():

while (in.hasNext()) {
    String s = in.next();
    if (s.equals("end")) {
      break;
    }
    System.out.println("The value of i is: " + i + " and you entered " + s);
    i++;
}
Run Code Online (Sandbox Code Playgroud)

我认为这比把一切都压缩成for表达要容易得多.

  • 我要支持这一个.对于具有未知迭代长度的循环,`while`循环_is_更好的做法. (6认同)

200*_*ess 6

此代码存在多个问题:

  1. s 在初始赋值后永远不会改变,所以它是一个无限循环.
  2. 打电话.next()可以扔NoSuchElementExceptionIllegalStateException.我没有考虑到这些例外情况,而是认为.hasNext()事先检查更有礼貌,因为输入输出是可预见的而不是特殊情况.然而,替代性请求宽恕方式也是可以接受的.
  3. for-loop标题不会形成一个连贯的故事 - 它初始化s和测试s,但更新i.
  4. 在我看来,与串联相比System.out.format()会稍微更优选System.out.println().

我会把它写成:

Scanner in = new Scanner(System.in);
int i = 0;
String s;
while (in.hasNext() && !"end".equals(s = in.next())) {
    System.out.format("The value of i is: %d and you entered %s\n", i++, s);
}
Run Code Online (Sandbox Code Playgroud)

它也可能是一个很好的用户界面触摸,告诉用户end终止循环是一个神奇的词(假设它被修改为可能的工作).


Chr*_*gis 2

这不是一个好主意,因为字符串s可能永远不等于"end"。您可能想检查扫描仪是否有另一个字符串。此外,您只需将字符串初始化为in.next(),但需要s在每次循环迭代后设置为下一个字符串。

while(in.hasNext()) {
  String s = in.next();
  if (s.equals("end")) {
    break;
  }
  // ..
}
Run Code Online (Sandbox Code Playgroud)