内容


第 9 单元:循环

迭代代码或反复执行它

Comments

开始之前

本单元是 “Java 编程入门” 学习路径的一部分。尽管各单元中讨论的概念具有独立性,但实践组件是在您学习各单元的过程中逐步建立起来的,推荐您在继续学习之前复习 前提条件、设置和单元细节

单元目标

  • 了解循环的用途
  • forwhiledo...while 语句使用正确的语法
  • 了解如何打破循环,或者跳过循环迭代并继续

什么是循环?

有时您希望代码在工作完成之前反复做同一件事。可使用循环 实现此目的。循环是一种编程结构,它在满足某个特定条件(或某组条件)时反复执行。例如,您可能要求程序读取数据文件中的所有记录,或者依次处理数组中的每个元素。(下一单元将介绍数组。)

3 种循环结构使迭代代码或多次执行它成为可能:

  • for 循环
  • while 循环
  • do...while 循环

for 循环

Java 语言中基本的循环结构是 for 语句。可以使用 for 语句迭代一个值范围,以确定执行循环多少次。for 循环的抽象语法是:

for (initialization; loopWhileTrue; executeAtBottomOfEachLoop) {
  statementsToExecute
}

在循环的开头,执行初始化语句(多个初始化语句可使用逗号分开)。只要 loopWhileTrue(一个必须计算为 truefalse 的 Java 条件表达式)为 true,就会执行该循环。在循环的底部,执行 executeAtBottomOfEachLoop

例如,如果希望清单 1 中的 main() 方法中的代码执行 3 次,可以使用一个 for 循环

清单 1. 一个 for 循环
public static void main(String[] args) {
  Logger l = Logger.getLogger(Person.class.getName());
  for (int aa = 0; aa < 3; aa++) {
    Person p = new Person("Joe Q Author", 42, 173, 82, "Brown", "MALE");
    l.info("Loop executing iteration# " + aa);
    l.info("Name: " + p.getName());
    l.info("Age:" + p.getAge());
    l.info("Height (cm):" + p.getHeight());
    l.info("Weight (kg):" + p.getWeight());
    l.info("Eye Color:" + p.getEyeColor());
    l.info("Gender:" + p.getGender());
  }
}

在清单 1 的开头,局部变量 aa 被初始化为 0。此语句仅在循环初始化时执行一次。该循环然后继续执行 3 次,每次将 aa 递增 1。

在下一单元将会看到,可使用一种替代性的 for 循环语法来循环执行实现 Iterable 接口的结构(比如数组和其他 Java 实用程序类)。就现在而言,只需注意 清单 1 中的 for 循环语法的用法。

一个 while 循环

while 循环的语法是:

while (condition) {
  statementsToExecute
}

正如您可能预料到的,如果 condition 计算为 true,则执行该循环。在每个迭代的顶部(也即在执行任何语句之前),计算该条件。如果该条件计算为 true,则执行循环。所以如果一个 while 循环的条件表达式至少有一次未计算为 true,则可能不执行该循环。

再次看看 清单 1 中的 for 循环。作为对比,清单 2 使用了一个 while 循环来获取同样的结果。

清单 2. 一个 while 循环
public static void main(String[] args) {
  Logger l = Logger.getLogger(Person.class.getName());
  int aa = 0;
  while (aa < 3) {
    Person p = new Person("Joe Q Author", 42, 173, 82, "Brown", "MALE");
    l.info("Loop executing iteration# " + aa);
    l.info("Name: " + p.getName());
    l.info("Age:" + p.getAge());
    l.info("Height (cm):" + p.getHeight());
    l.info("Weight (kg):" + p.getWeight());
    l.info("Eye Color:" + p.getEyeColor());
    l.info("Gender:" + p.getGender());
    aa++;
  }
}

可以看到,while 循环需要的工作比 for 循环要多。您必须初始化 aa 变量,还要记住在循环底部递增它。

do...while 循环

如果想要一个始终执行一次,然后 检查它的条件表达式的循环,可以使用 do...while 循环,如清单 3 所示。

清单 3. 一个 do...while 循环
int aa = 0;
do {
  Person p = new Person("Joe Q Author", 42, 173, 82, "Brown", "MALE");
  l.info("Loop executing iteration# " + aa);
  l.info("Name: " + p.getName());
  l.info("Age:" + p.getAge());
  l.info("Height (cm):" + p.getHeight());
  l.info("Weight (kg):" + p.getWeight());
  l.info("Eye Color:" + p.getEyeColor());
  l.info("Gender:" + p.getGender());
  aa++;
} while (aa < 3);

条件表达式 (aa < 3) 在循环结束前不会执行检查。

循环终止

有时,您需要在条件表达式计算为 false 之前跳出(或终止)循环。如果在一个 String 数组中搜索某个特定值,而且只想找到该值,并不关心数组的其他元素,则可能发生这种情况。对于想要跳出循环的情况,Java 语言提供了 break 语句,如清单 4 所示。

清单 4. 一条 break 语句
public static void main(String[] args) {
  Logger l = Logger.getLogger(Person.class.getName());
  int aa = 0;
  while (aa < 3) {
    if (aa == 1)
      break;
    Person p = new Person("Joe Q Author", 42, 173, 82, "Brown", "MALE");
    l.info("Loop executing iteration# " + aa);
    l.info("Name: " + p.getName());
    l.info("Age:" + p.getAge());
    l.info("Height (cm):" + p.getHeight());
    l.info("Weight (kg):" + p.getWeight());
    l.info("Eye Color:" + p.getEyeColor());
    l.info("Gender:" + p.getGender());
    aa++;
  }
}

break 语句跳转到它所在循环外的下一条可执行语句。

继续执行循环

清单 4 中的(简化)例子中,您仅希望执行循环一次并跳出。也可跳过循环的单次迭代,但继续执行循环。要实现该目的,需要使用 continue 语句,如清单 5 所示。

清单 5. 一条 continue 语句
public static void main(String[] args) {
  Logger l = Logger.getLogger(Person.class.getName());
  int aa = 0;
  while (aa < 3) {
    if (aa == 1)
      continue;
    else
    aa++;
    Person p = new Person("Joe Q Author", 42, 173, 82, "Brown", "MALE");
    l.info("Loop executing iteration# " + aa);
    l.info("Name: " + p.getName());
    l.info("Age:" + p.getAge());
    l.info("Height (cm):" + p.getHeight());
    l.info("Weight (kg):" + p.getWeight());
    l.info("Eye Color:" + p.getEyeColor());
    l.info("Gender:" +
    p.getGender());
  }
}

在清单 5 中,跳过了循环的第二次迭代,但继续执行第三次迭代。举例而言,在处理记录并遇到一条您完全不想处理的记录时,使用 continue 就很方便。您可以跳过该记录并前进到下一条记录。

测试您的理解情况

  1. 第 7 单元 中,在 getName() 实现中使用 concat() 方法演示了方法链。使用字符串串联(通过 + 运算符)实现 getName() 方法。编写一个 JUnit 测试来确保结果符合预期。
  2. 哪个(哪些)运算符是二元运算符?
    1. ++
    2. +
    3. %
    4. --
    5. +=
    6. a、b 和 d
    7. b、c 和 e
    8. 上述选项都不是
  3. 字符串串联 表示组合两个或更多字符串的内容形成一个更大的字符串。
  4. 以下哪个语句表示 “如果 a 小于或等于 b”?
    1. if (a lt b)
    2. if (b < a)
    3. if (b +< a)
    4. if (a <= b)
    5. 上述选项都不是
  5. 执行以下代码块后,变量 c 的值是多少?解释您的答案。

       public int method1() {
          int a = 10;
          int b = 7;
          int c = 0;
          
          if (b >= a)
             c++;
             b = -47;
          if (b > c)
             c = b;
          
          return c;
       }
  6. 以下代码是否会被编译?解释您的答案。

       public int method2() {
          int a = 0;
          
          if (a > 0) {
             int b = a;
          }
          
          int c = b;
          
          return c;
       }
  7. 执行以下代码块后,变量 c 的值是多少?解释您的答案。

       public boolean method3() {
          boolean a = true;
          boolean b = false;
          boolean c;
          
          if (a = b) 
             c = false;
          else
             c = a;
          
          return c;
       }
  8. for 循环始终 至少执行一次。
  9. 在循环的底部检查确定 do...while 循环是否继续执行的条件。
  10. 编写一个包含 for 循环的方法,该循环从 3 开始,循环 6 次,并使用 JDK Logger 输出迭代次数(从 1 开始)及当前循环变量。使用 清单 1 作为使用 Logger 的示例。使用您的 Logger 输出验证结果。
  11. 使用不同的方法名重复问题 10 中的练习,但这次使用一个 while 循环。使用您的 Logger 输出验证结果。
  12. 使用 do...while 循环重复问题 10 中的练习。使用您的 Logger 输出验证结果。
  13. 编写一个包含 for 循环的方法,该循环从零 (0) 开始,循环十 (10) 次,并使用 JDK Logger 类输出迭代次数(从 1 开始)及当前循环变量。跳过第 4、5 和 9 次迭代。使用您的 Logger 输出验证结果。

核对您的答案

进一步探索

Java 教程:while 和 do-while 语句

Java 教程:for 语句

Java— 循环控制

上一单元:条件运算符和控制语句下一单元:Java 集合


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Java technology
ArticleID=1038562
ArticleTitle=第 9 单元:循环
publish-date=10172016