循环块
导航 语言基础 主题: ) |
循环是一种便捷的工具,使程序员能够以最少的努力完成重复的任务。假设我们想要一个可以从 1 到 10 计数的程序,我们可以编写 以下程序。
|
|
任务将顺利完成,数字 1 到 10 将在输出中打印,但此解决方案存在一些问题。
- 灵活性:如果我们想更改起始数字或结束数字怎么办?我们必须遍历并更改它们,在需要的地方添加额外的代码行。
- 可扩展性:10 次重复是微不足道的,但如果我们想要 100 次甚至 1000 次重复怎么办?对于大量迭代,所需的代码行数将非常多。
- 维护性:代码量大时,更容易出错。
- 特性:任务数量是固定的,不会在每次执行时改变。
使用循环,我们可以解决所有这些问题。一旦你掌握了它们,它们将成为解决编程中许多问题的宝贵工具。
打开你的编辑程序,创建一个名为 Loop.java
的新文件。现在输入或复制 以下代码
|
|
如果我们运行该程序,将产生相同的结果,但查看代码,我们立即看到了循环的优势。而不是执行十行不同的代码,第 5 行执行十次。十行代码已经减少到只有四行。此外,我们可以将数字 10 更改为我们喜欢的任何数字。自己试试,将 10 替换为你自己的数字。
while
循环是最简单的循环形式。while
循环重复执行代码块,直到指定的条件为真。以下是一个 while
循环的结构。
while (布尔表达式1) {
} |
在每次循环迭代之前,都会检查循环的条件。如果在循环开始时条件为假,则循环将不会执行。在 代码部分 3.28 中,squareHigherThan200
设置了平方大于 200 的最小整数。
代码部分 3.28:平方大于 200 的最小整数。
int squareHigherThan200 = 0;
while (squareHigherThan200 * squareHigherThan200 < 200) {
squareHigherThan200 = squareHigherThan200 + 1;
}
|
如果循环的条件永远不会变为假,例如,如果使用 true 常量作为条件,则该循环被称为无限循环。这样的循环会无限期地重复,除非它被 break 语句中断。无限循环可以用来执行需要不断重复而不确定停止点的任务,例如更新图形显示。 |
do
-while
循环的功能类似于 while
循环,只是条件是在语句执行之后才评估的。当我们尝试通过随机浏览一组数据来查找起作用的数据时,它非常有用。
do {
} while (布尔表达式1); |
for
循环是一个专门的 while
循环,其语法旨在方便地遍历数字序列。它由关键字 for
以及括号中包含的三个额外语句组成。第一个语句是变量声明语句,它允许你声明一个或多个整型变量。第二个是条件,其检查方式与 while
循环相同。最后一个是迭代语句,用于递增或递减变量,尽管任何语句都是允许的。
这是一个 for
循环的结构。
for (变量声明; 条件; 迭代语句) {
} |
为了说明如何使用 for 循环,以下是一个示例。
|
|
for
循环就像 while
循环的模板版本。使用 while
循环的替代代码如下:
代码部分 3.30:使用 while 循环的迭代。
int i = 1;
while (i <= 10) {
System.out.println(i);
i++;
}
|
在 代码部分 3.31 中,展示了如何使用多个变量使用 for
循环进行迭代,而 代码部分 3.32 展示了如何跳过 for
循环的任何参数。跳过所有参数,你就会得到一个无限循环。
|
|
数组 还没有讲到,但你会想知道如何使用增强 for 循环,称为 for-each
循环。for-each
循环会自动遍历列表或数组,并将每个索引的值分配给一个变量。
要了解 for-each
循环的结构,请查看以下示例。
代码部分 3.33:一个 for-each 循环。
String[] sentence = {"I", "am", "a", "Java", "program."};
for (String word : sentence) {
System.out.print(word + " ");
}
|
代码部分 3.33 的输出
I am a Java program. |
该示例遍历了一个单词数组,并将它们像句子一样打印出来。循环所做的事情是遍历 sentence
,并将每个索引的值分配给 word
,然后执行代码块。
以下是 for-each
循环的一般约定。
for (变量声明 : 数组或列表) {
} |
确保数组或列表的类型可以分配给声明的变量,否则你会遇到编译错误。注意,循环会在检查完集合中的最后一个项目后自动退出语句块。
虽然增强 for 循环可以使代码更清晰,但它不能用于一些常见情况。
- 只能访问。 元素不能被赋值,例如,不能递增集合中的每个元素。
- 只能单个结构。 无法同时遍历两个结构,例如,比较两个数组。
- 只能单个元素。 仅用于访问单个元素,例如,不能比较连续的元素。
- 只能向前。 只能按单步向前迭代。
- 至少 Java 5。 如果需要与 Java 5 之前的版本兼容,请不要使用它。
break
关键字退出流程控制循环,例如 for 循环。它基本上是中断循环。
在 代码部分 3.34 中,循环将打印出从 1 到 10 的所有数字,但我们有一个检查,当 i
等于 5 时会执行。当循环到达第五次迭代时,它将被 break
语句中断,此时它将退出循环。
|
|
continue
关键字直接跳转到循环的下一个迭代,并评估控制循环的布尔表达式。 代码部分 3.35 是 continue
语句在实际应用中的示例
|
|
由于 break
和 continue
语句会降低代码的可读性,建议减少使用它们,或用 if
和 while
块替换它们。由于这些语句的存在,一些 IDE 重构操作可能会失败。
问题 3.2:考虑以下代码
问题 3.2:循环和条件。
int numberOfItems = 5;
int currentItems = 0;
int currentCandidate = 1;
while (currentItems < numberOfItems) {
currentCandidate = currentCandidate + 1;
System.out.println("Test with integer: " + currentCandidate);
boolean found = true;
for (int i = currentCandidate - 1; i > 1; i--) {
// Test if i is a divisor of currentCandidate
if ((currentCandidate % i) == 0) {
System.out.println("Not matching...");
found = false;
break;
}
}
if (found) {
System.out.println("Matching!");
currentItems = currentItems + 1;
}
}
System.out.println("Find the value: " + currentCandidate);
|
标准输出中将打印什么?
问题 3.2 的输出
Test with integer: 2 Matching! Test with integer: 3 Matching! Test with integer: 4 Not matching... Test with integer: 5 Matching! Test with integer: 6 Not matching... Test with integer: 7 Matching! Test with integer: 8 Not matching... Test with integer: 9 Not matching... Test with integer: 10 Not matching... Test with integer: 11 Matching! Find the value: 11 |
这段代码片段正在搜索第 5 个 质数,也就是:11。它迭代从 2 开始的每个正整数(2、3、4、5、6、7、8、9、10、11...),其中,它统计质数(2、3、5、7、11)并在第 5 个质数处停止。
因此,代码片段首先使用 while
循环迭代从 2 开始的每个正整数
答案 3.2.1:while 循环。
int numberOfItems = 5;
int currentItems = 0;
int currentCandidate = 1;
while (currentItems < numberOfItems) {
currentCandidate = currentCandidate + 1;
System.out.println("Test with integer: " + currentCandidate);
boolean found = true;
for (int i = currentCandidate - 1; i > 1; i--) {
// Test if i is a divisor of currentCandidate
if ((currentCandidate % i) == 0) {
System.out.println("Not matching...");
found = false;
break;
}
}
if (found) {
System.out.println("Matching!");
currentItems = currentItems + 1;
}
}
System.out.println("Find the value: " + currentCandidate);
|
对于每一次迭代,当前数字要么是质数,要么不是。如果是质数,则执行左侧的代码。如果不是质数,则执行右侧的代码。
答案 3.2.2:一个质数。
int numberOfItems = 5;
int currentItems = 0;
int currentCandidate = 1;
while (currentItems < numberOfItems) {
currentCandidate = currentCandidate + 1;
System.out.println("Test with integer: " + currentCandidate);
boolean found = true;
for (int i = currentCandidate - 1; i > 1; i--) {
// Test if i is a divisor of currentCandidate
if ((currentCandidate % i) == 0) {
System.out.println("Not matching...");
found = false;
break;
}
}
if (found) {
System.out.println("Matching!");
currentItems = currentItems + 1;
}
}
System.out.println("Find the value: " + currentCandidate);
|
答案 3.2.3:不是一个质数。
int numberOfItems = 5;
int currentItems = 0;
int currentCandidate = 1;
while (currentItems < numberOfItems) {
currentCandidate = currentCandidate + 1;
System.out.println("Test with integer: " + currentCandidate);
boolean found = true;
for (int i = currentCandidate - 1; i > 1; i--) {
// Test if i is a divisor of currentCandidate
if ((currentCandidate % i) == 0) {
System.out.println("Not matching...");
found = false;
break;
}
}
if (found) {
System.out.println("Matching!");
currentItems = currentItems + 1;
}
}
System.out.println("Find the value: " + currentCandidate);
|
质数使用 currentItems
计数。当 currentItems
等于 numberOfItems
(5)时,程序退出 while
循环。currentCandidate
包含最后一个数字,也就是第 5 个质数
答案 3.2.4:程序结束。
int numberOfItems = 5;
int currentItems = 0;
int currentCandidate = 1;
while (currentItems < numberOfItems) {
currentCandidate = currentCandidate + 1;
System.out.println("Test with integer: " + currentCandidate);
boolean found = true;
for (int i = currentCandidate - 1; i > 1; i--) {
// Test if i is a divisor of currentCandidate
if ((currentCandidate % i) == 0) {
System.out.println("Not matching...");
found = false;
break;
}
}
if (found) {
System.out.println("Matching!");
currentItems = currentItems + 1;
}
}
System.out.println("Find the value: " + currentCandidate);
|
标签
[edit | edit source]标签可用于为循环命名。这样做的原因是,我们可以从嵌套循环中退出或继续上级循环。
以下是为循环添加标签的方法
标签名称:循环 |
要退出或继续循环,请使用 break
或 continue
关键字,后面跟着循环的名称。
例如
|
|
如果你不理解所有代码,也不用担心,但请注意标签是如何用于从内循环退出外循环的。但是,由于这种代码难以阅读和维护,强烈建议不要使用标签。
尝试... 捕获块
[edit | edit source]- 另请参阅 抛出和捕获异常。
try
-catch
块用于捕获代码中的任何异常或其他可抛出对象。
以下是 try-catch
块的样子
try {
} catch (exception1) {
} |
代码清单 3.6 尝试打印传递给程序的所有参数。但是,如果参数不足,它将抛出异常。
代码清单 3.6:Attempt.java
public class Attempt {
public static void main(String[] args) {
try {
System.out.println(args[0]);
System.out.println(args[1]);
System.out.println(args[2]);
System.out.println(args[3]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Not enough arguments");
}
}
}
|
除了 try 和 catch 块之外,还可以使用 finally
块。无论是否抛出异常,都会始终执行 finally 块。它可以与 catch 块一起出现,也可以不与 catch 块一起出现,但始终与 try 块一起出现。
以下是 finally 块的样子
try {
} catch (exception1) {
} finally {
} |
示例
[edit | edit source]代码清单 3.7 接收一个数字作为参数,并打印它的二进制表示。
代码清单 3.7:GetBinary.java
public class GetBinary {
public static void main(String[] args) {
if (args.length == 0) {
// Print usage
System.out.println("Usage: java GetBinary <decimal integer>");
System.exit(0);
} else {
// Print arguments
System.out.println("Received " + args.length + " arguments.");
System.out.println("The arguments are:");
for (String arg : args) {
System.out.println("\t" + arg);
}
}
int number = 0;
String binary = "";
// Get the input number
try {
number = Integer.parseInt(args[0]);
} catch (NumberFormatException ex) {
System.out.println("Error: argument must be a base-10 integer.");
System.exit(0);
}
// Convert to a binary string
do {
switch (number % 2) {
case 0: binary = '0' + binary; break;
case 1: binary = '1' + binary; break;
}
number >>= 1;
} while (number > 0);
System.out.println("The binary representation of " + args[0] + " is " + binary);
}
}
|
代码清单 3.8 模拟玩一个名为幸运七的游戏。这是一个骰子游戏,玩家掷两个骰子。如果骰子上的数字加起来是七,他就赢了 4 美元。如果不是,他就输了 1 美元。这个游戏展示了如何在程序中使用控制流以及赌博的徒劳无益。
代码清单 3.8:LuckySevens.java
import java.util.*;
public class LuckySevens {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Random random = new Random();
String input;
int startingCash, cash, maxCash, rolls, roll;
// Loop until "quit" is input
while (true) {
System.out.print("Enter the amount of cash to start with (or \"quit\" to quit): ");
input = in.nextLine();
// Check if user wants to exit
if (input.toLowerCase().equals("quit")) {
System.out.println("\tGoodbye.");
System.exit(0);
}
// Get number
try {
startingCash = Integer.parseInt(input);
} catch (NumberFormatException ex) {
System.out.println("\tPlease enter a positive integer greater than 0.");
continue;
}
// You have to start with some money!
if (startingCash <= 0) {
System.out.println("\tPlease enter a positive integer greater than 0.");
continue;
}
cash = startingCash;
maxCash = cash;
rolls = 0;
roll = 0;
// Here is the game loop
for (; cash > 0; rolls++) {
roll = random.nextInt(6) + 1;
roll += random.nextInt(6) + 1;
if (roll == 7)
cash += 4;
else
cash -= 1;
if (cash > maxCash)
maxCash = cash;
}
System.out.println("\tYou start with $" + startingCash + ".\n"
+ "\tYou peak at $" + maxCash + ".\n"
+ "\tAfter " + rolls + " rolls, you run out of cash.");
}
}
}
|