使用Java语句决定和迭代

Java应用程序在语句的上下文中评估表达式,这些语句是独立的代码岛,完成各种任务,例如声明变量,做出决定或迭代语句。语句可以表示为简单语句或复合语句:

  • 一个简单的语句是用于执行任务的一个独立的指令; 它必须用分号字符(;)终止。
  • 一个复合语句是位于开放和近距离括号字符(之间的简单和其它复合语句序列{}),这限定了复合语句的边界。复合语句可以为空,将出现在简单语句的任何地方,或者称为。复合语句不以分号结束。

在本文中,我将介绍您在Java程序中使用语句。你可以使用语句声明变量和指定表达式,做决定,迭代语句(是的,你可以使用语句迭代语句),断开和继续迭代,什么也不做。我将为未来的Java 101文章留下一些更加奇异的语句(如用于从被调用的方法返回值和抛出异常的语句)。


声明变量并将表达式指定为语句

在本系列的前面,我介绍了变量的概念,并提到变量必须在使用之前声明。我还提到一个变量声明最少包含一个类型名称,可选地后跟一对方括号对的序列,后跟一个名称,可选地后跟一对方括号对的序列,并以分号结束。此外,变量可以在其声明期间被显式初始化。

因为变量声明是一个独立的代码岛,它实际上是一个语句 - 一个简单的语句。这里有一些示例变量声明语句:

int age = 25;
float interest_rate;
char[] text = { 'J', 'a', 'v', 'a' };
String name;

与变量声明语句紧密相关的是赋值语句,它为变量赋值(可能是对数组的引用或对对象的引用)。下面是几个例子:

age = 30;
interest_rate = 4.0F;
age += 10;
text[1] = 'A';
text[2] = 'V';
text[3] = 'A';
name = "John Doe";

赋值语句是一个的例子表达式语句,它是如果它随后用分号,可以使用作为语句的表达式。以下表达式也有资格作为表达式语句:

  • 预增(例如,++x;
  • 预处理(例如,--y;
  • 后增量(例如x++;
  • 后付款(例如y--;
  • 方法调用(例如,System.out.println("Hello");
  • 对象创建(例如,new String("ABC");

做出决定

决策语句允许应用程序在多个执行路径之间进行选择。例如,如果销售人员本月销售的物品超过500件,则给销售人员一个奖金。此外,如果学生在代数测试中的成绩大于85%,则祝贺学生表现良好; 否则,建议学生更努力地学习下一个测试。

Java的支持ififelseswitch决策声明。

if语句

最简单的Java决策语句是if语句,它评估一个布尔表达式,并在该表达式的值为true时执行另一个语句。该if语句的语法如下:

if (Boolean expression)
   statement

if声明与保留字开头if,并用括号中的布尔表达式,这是后面的语句执行时,布尔表达式为true继续。

以下示例演示该if语句。当age变量包含值为55或更大时,if执行System.out.println(...);以输出消息:

if (age >= 55)
   System.out.println("You are or were eligible for early retirement.");

许多人喜欢将任何简单语句if包含在大括号中的语句后,有效地将其转换为等效的复合语句:

if (age >= 55)
{
   System.out.println("You are or were eligible for early retirement.");
}

虽然大括号清楚了if语句执行的内容,但我相信缩进提供了这种清晰度,并且大括号是不必要的。但是,您可能更喜欢指定大括号。

if-else语句

ifelse语句计算一个布尔表达式,当这个表达式的值为true执行一条语句,当计算结果为false执行另一个语句。以下是ifelse语句的语法:

if (Boolean expression)
   statement1
else
   statement2

ifelse语句类似if的语句,而且还包括保留字else后跟一个语句时,布尔表达式为假的处理。

以下示例演示了一个ifelse语句,告诉年龄小于55岁的人,直到提前退休的剩余时间:

if (age >= 55)
   System.out.println("You are or were eligible for early retirement.");
else
   System.out.println("You have " + (55 - age) + " years to go until early retirement.");

条件运算符vs if-else

条件运算符(?:)类似于ifelse语句。但是,此运算符不能用于执行备用语句。相反,它只能返回同一类型的两个值之一。

链接if-else语句

Java允许您链多ifelse陈述在一起,你需要选择多个语句执行的一个情况。生成的语法如下所示:

if (Boolean expression1)
   statement1
else
if (Boolean expression2)
   statement2
else
   ...
else
   statementN

只要当前语句的布尔表达式求值为false ,链接就会执行后续的ifelse语句if。以下示例提供了此链接行为的演示:

if (temperature < 0.0)
   System.out.println("freezing");
else
if (temperature > 100.0)
   System.out.println("boiling");
else
   System.out.println("normal");

第一ifelse声明确定temperature的价值为负。如果是,它执行System.out.println("freezing");。如果不是,它执行第二ifelse

第二个ifelse确定temperature其值是否大于100.如果是,则执行System.out.println("boiling");。否则,它执行System.out.println("normal");

悬而未决的问题

ififelse一起使用时,和源代码是不正确的缩进,可能难以确定哪些if与相关联else。以下示例演示此问题:

int x = 0;
int y = 2;
if (x > 0)
   if (y > 0)
      System.out.println("x > 0 and y > 0");
else
   System.out.println("x <= 0");

在这个例子中,你可能期望看到x <= 0输出。但这绝不会发生,相反没有什么会输出。该else到其最近的比赛if,这是if (y > 0)。一旦这个例子重新格式化,你可以更清楚地看到发生了什么:

int x = 0;
int y = 2;
if (x > 0)
   if (y > 0)
      System.out.println("x > 0 and y > 0");
   else
      System.out.println("x <= 0");

正如你所看到的,语句后面是一个if (y > 0) ... else ... if- 语句。要创建上一个示例的意图,您需要引入括号字符及其后续语句。基本上,一个块将遵循:elseif (x > 0)if (y > 0)if (x > 0)

int x = 0;
int y = 2;
if (x > 0)
{
   if (y > 0)
      System.out.println("x > 0 and y > 0");
}
else
   System.out.println("x <= 0");

因为x > 0计算结果为false,System.out.println("x <= 0");执行。该else保留字匹配明确最多if (x > 0)

switch语句

switch声明让您从几个执行路径中更有效地比使用等效串连选择ifelse报表。它具有以下语法:

switch (selector expression)
{
   case value1: statement1 [break;]
   case value2: statement2 [break;]
   ...
   case valueN: statementN [break;]
   [default: statement]
}

switch语句从保留字开始,switch并继续选择一个选择器表达式,该选择器表达式选择后续情况之一或默认情况执行。选择器表达式的计算结果为整数,字符或字符串。

开关和枚举常量

选择器表达式也可以求值为enum常数。我将enum在以后的文章中讨论。

每个案例标识要执行的语句。情况从保留字case和标记大小写的值开始。以冒号(:)字符是要执行的语句。该语句可以选择性地后跟break;,将执行转移到第一个语句之后switch。如果没有任何案例标签与选择器表达式的值匹配default,则将执行以保留字开头的可选缺省案例。

以下示例演示了一个switch语句,该语句确定整数值是偶数还是奇数(通过使用remainder运算符),然后通过其标签与其余部分匹配的大小写输出适当的消息:

int i = 27;
switch (i % 2)
{
   case 0: System.out.println("even");
           break;

   case 1: System.out.println("odd");
}

此示例输出odd,因为i % 2产生1,其匹配第二个case标签。如果我省略break;,如果数字是偶数,even后面是odd输出,因为执行将落到第二种情况。

断开您的交换机

忘记使用“ break;” 结束案例是使用switch语句时常见的错误。

有时,希望执行到下一个情况。例如,假设您要响应用户指定的大写或小写命令行选项字母,执行常用代码:

switch (args[i])
{
   case "-v":
   case "-V": System.out.println("Version 1.0");
              break;

   // ...

   default  : System.out.println("unknown option");
}

假设一个for语句(稍后讨论)正在遍历传递给应用程序main()方法的命令行参数数组中的每个参数。如果参数是-v(破折号和小写字母v)或-V(破折号和大写字母V),则会输出应用程序的版本号。当-v指定时,有必要执行到以下情况,在指定时输出版本号-V

每当引用的字符串args[i]与任何案例标签不匹配时,都会执行默认情况。换句话说,用户已经指定了未知选项。

链接if-else vs开关

有时,你可能需要一个链接之间进行选择ifelse语句和等价switch语句。你选择的声明应该提供最大的清晰度,对于手头的任务最少的冗长。

迭代语句

迭代语句(也称为循环语句)对特定数量的迭代(循环)或无限地重复执行其他语句,直到出现某些终止条件。例如,如前所述,您可能想要遍历String传递给main()方法的命令行参数数组中的所有对象。Java的支持forwhile以及dowhile循环语句。

for语句

for语句执行另一个语句的时间或无限期地一个具体的数字。它本质上是语句的紧凑形式while(稍后讨论),并具有以下语法:

for ([initialize]; [test]; [update])
   statement

此语法显示for语句从保留字开始,for并以三个部分的括号分隔和分号分隔的序列继续:

  • initialize:变量声明或赋值的逗号分隔列表。这些变量称为迭代变量循环变量,用于索引数组,参与计算或执行其他任务。
  • test:一个布尔表达式,决定循环执行的时间。只要此表达式保持真实,执行就会继续。
  • update:通常修改循环变量的表达式的逗号分隔列表。

下面的for语句是a statement重复执行。

三个部分中的每一个是可选的。结果,for可以缩小到for (; ;)。因为没有停止条件,所以产生的循环被称为无限循环

以下示例使用for语句对名为数组的所有元素进行迭代args,输出每个数组元素的值:

for (int i = 0; i < args.length; i++)
   System.out.println(args[i]);

此示例工作如下:

  1. 声明变量i并将其初始化为0
  2. 评估i < args.length。如果i相等args.length,终止循环。
  3. 执行System.out.println(args[i]);
  4. 执行i++
  5. 继续执行步骤2。

变量ifor语句的testupdate部分可见,并且对statement。但是,对后续语句不可见。如果您希望后续语句查看i最终值,请i在之前声明for,如下所示:

int i;
for (i = 0; i < args.length; i++)
   System.out.println(args[i]);

控制循环的变量可以是不同的基本类型,例如布尔,字符或双精度浮点。这里有三个例子:

for (boolean b = false; b != true; b = !b)
   System.out.println(b); // This statement executes once.

for (char c = 'A'; c <= 'F'; c++)
   System.out.println(c);

for (double d = 0.0; d < 1.0; d += 0.1)
   System.out.println(d);

最后,如前所述,该initialize节可以声明多个变量。以下示例声明两个变量,在整个循环中递增一个变量并递减另一个变量:

for (int i = 0, j = 5; i <= 5; i++, j--)
   System.out.println(i + j);

输出由六行组成5

while语句

while语句重复执行另一个语句,而其控制布尔表达式保持求值为true。此语句具有以下语法:

while (Boolean expression)
   statement

此语法显示while语句以保留字while开头,并以括号布尔表达式继续。此语句后面是另一个重复执行的语句。

以下示例演示了while语句:

int i = 0;
while (i < args.length)
{
   System.out.println(args[i]);
   i++;
}

此示例工作如下:

  1. 声明变量i并将其初始化为0
  2. 评估i < args.length。如果i相等args.length,终止循环。
  3. 执行System.out.println(args[i]);
  4. 执行i++
  5. 继续执行步骤2。

此示例while等效于上一个for示例。您可以压缩示例以重复执行简单语句,而不是复合语句,如下所示:

int i = 0;
while (i < args.length)
   System.out.println(args[i++]);

在这个压缩的示例中,我将postincrement语句更改为一个传递给数组索引运算符的表达式。虽然代码更紧凑,但为了清楚起见,您可能更喜欢前面的示例。

do-while语句

dowhile语句重复执行的声明,而其控制布尔表达式,执行语句之后进行评估,计算结果为true。此语句具有以下语法:

do
   statement
while (Boolean expression); // The semicolon terminator is mandatory.

此语法显示一个dowhile语句从保留字开始do,继续使用一个重复执行的语句,并以保留字结束while,后跟一个括号布尔表达式。

以下示例演示了dowhile语句:

int ch;
do
{
   System.out.println("Press x to continue.");
   ch = System.in.read();
}
while (ch != 'x');

此示例工作如下:

  1. 声明int变量ch以存储字符的数字代码。
  2. 提示用户按x键继续。
  3. 从键盘通过读取键代码System.in.read(),这是一个伴随的System.out.println()。因为此方法将键的代码返回为int,所以将此值赋给ch
  4. 比较ch的值与'x'。注意,'x'从比较之前char到比较int之前加宽。当此表达式的计算结果为false(ch等于'x')时,终止循环。否则,请继续执行步骤2。

whileand do- 之间的区别whilewhile执行其语句零次或多次,而dowhile执行其语句一次或多次。您将基于此属性选择任一语句。例如,适合使用while迭代args数组,因为此数组可能长度为零,并且您不希望在这种情况下访问数组(并引发超出边界异常,这将在以后的文章中讨论) )。相反,您将使用dowhile(和引发一个超出边界异常)访问数组至少一次。使用dowhile提示用户输入密钥并读取响应是合适的,因为这些任务必须至少发生一次。

打破和继续迭代

您之前在break语句的上下文中看到了switch语句,用于switch在案例执行后断开语句。然而,这个语句也可以在迭代语句上下文中使用,我将在本节中讨论。我也讨论了continue语句,它只能在迭代语句上下文中使用。您将探索这些语句的未标记和已标记版本。

未标记的break和标记的break语句

无标签的break声明终止switchforwhile,或者dowhile通过转移执行的第一条语句下面这句话的语句。它具有以下语法:

break;

以下示例演示break迭代语句上下文中的未标记语句:

for (; ;)
{
   System.out.println("Press x to continue.");
   int ch = System.in.read();
   if (ch == 'x')
      break;
}

此示例介绍了一个for基于无限循环,重复提示用户按x键并读取此键,直到其等于'x'。一个if语句执行比较,执行break;以在按x键时终止循环。

无限循环

你可以创建基于等效无限循环whiledowhile通过指定的语句true作为布尔表达式(例如,while (true) ...do ... while (true);)。虽然你通常想要避免无限循环,这通常是由错误的代码产生的 - 例如,创建一个循环的布尔表达式基于==!=比较一个浮点变量的值和一个浮点值,不能在内存中精确表示为0.1) - 上面的示例显示了它们的一个用途。

标记的break语句终止含有和标签switchforwhile,或者dowhile通过转移执行的第一条语句包含的语句下面的语句。它具有以下语法:

break label;

该语法包括保留字,break后跟非保留字标识符作为标签,后跟分号。标签必须以前缀switch或迭代语句为前缀,并且必须后跟冒号。

以下示例演示break迭代语句上下文中的带标签语句:

outer:
while (true)
{
   System.out.println("Guess number between 0 and 9.");
   while (true)
   {
      System.out.println("Press n for new game or q to quit.");
      int ch = System.in.read();
      if (ch == 'n')
         break;
      if (ch == 'q')
         break outer;
   }
}

这个例子呈现了一对嵌套的无限while循环,它们描述了数字猜测游戏的一部分。外部循环是用于玩游戏的存根,而内部循环提示用户玩新游戏或退出游戏。

如果用户按下n键,break则执行未标记语句以终止内循环,从而可以播放新游戏。如果q被按下,break outer;则执行退出外部循环,其被分配outer:标签。

未标记的continue和标签continue语句

未标记continue语句跳过当前迭代的剩余部分,并指示迭代语句前进到下一次迭代。它具有以下语法:

continue;

下面是unlabeled continue语句的使用示例:

for (int i = -2; i <= 2; i++)
   if (i == 0)
      continue;
   else
      System.out.println(10 / i);

这个例子的for语句从迭代-22,重复执行一个ifelse语句,然后i在每次迭代后增加1。

为了防止i包含0 的除零异常,if测试i0.如果是这种情况,它会执行continue;,这导致for增量i然后求值i <= 2。否则,10 / i将求值并输出结果。

标记continue语句跳过一个或多个嵌套迭代语句的剩余迭代,并将执行转移到标记的迭代语句。它具有以下语法:

continue label;

该语法包括保留字,continue后跟非保留字标识符作为标签,后跟分号。标签必须以前一个迭代语句为前缀,并且必须后跟冒号。

这里有一个使用labeled continue语句的例子:

outer:
for (int i = -2; i <= 2; i++)
   for (int j = -2; j <= 2; j++)
      if (i == 0)
         continue outer;
      else
      if (j == 0)
         continue;
      else
         System.out.println(10 / i * j);

此示例呈现一对嵌套for循环,每个循环变量范围从-2到2.其思想是将10除以循环变量值的乘积。然而,当任一变量包含0时,将除以零。

为了避免被零除链式ifelse语句用于测试i的和j的为0。如果值i的值为0,continue outer;用来终止内部循环,推进外环(含标签outer:)过去0.如果j的值为0,continue;用于退出当前内循环迭代并将内循环提前0.如果两种情况都不出现,则执行计算并输出其结果。

什么也不做

有一个最终语句要考虑,这是一个空语句,一个语句只包含分号字符。这个语句什么都不做,但它是有用的。请考虑以下示例:

for (int ch; (ch = System.in.read()) != -1; System.out.print((char) ch));

此示例将标准输入流的内容(通过调用读取System.in.read())复制到标准输出流,通过调用写入System.out.print()System.out.println()即不输出行分隔符的随播广告。它在标准输入流从键盘重定向到文本文件时效果最好。

当重定向到文件时,System.in.read()当没有更多输入时返回-1。当不重定向时,System.in.read()从键盘获取其输入,从不返回-1。相反,当没有更多的键代码返回时,System.in.read()返回行分隔符字符 - 在Windows上需要两次调用以返回其\r\n字符,Unix \ Linux上需要调用一次以返回其\n字符,并且需要在旧的版本的Mac OS返回其\r字符。欲了解更多信息,请换行符

正如你可以看到的,所有的工作都在for语句initializetest节中执行。最后的分号是指空的语句,它被重复执行。

紧凑或不紧凑

一些开发人员会认为上一个示例是优雅的,因为它的紧凑性,而其他开发人员认为代码的紧凑性使其难以阅读和理解。你喜欢什么样式?

注意空语句,因为它可能是难以找到的错误的来源。例如,您可能希望以下语句for输出该单词的10个实例Hello

for (int i = 0; i < 10; i++);
   System.out.println("Hello");

相反,你将只观察这个单词的一个实例,因为for语句的右括号后面有一个空语句。for执行空语句10次,之后方法调用执行一次。

编写有趣的应用程序

现在,您已经探索了Java的所有基本语言功能,您已经准备好开始创建有趣的应用程序。例如,考虑一个随机选择从0到9的整数的猜测游戏,并要求您猜测此数字。如果你猜到太高或太低,游戏会告诉你。它也会告诉你,当你猜测,并会问你是否想再次播放。

在介绍游戏应用程序的源代码之前,我需要向您介绍这个源代码中尚未遇到的两个特性:

  • 我使用System.in.read()返回按键的代码(当标准输入未重定向时)或文件中的8位值(当标准输入重定向时)。System.in.read()能够抛出异常,所以我不得不附加“ throws Exception”到main()方法头,如public static void main(String[] args) throws Exception。这可以防止编译器报告错误。
  • 要获得一个随机整数,我需要调用random()标准类库的Math类的方法成员。random()返回一个范围从0.0到几乎1.0的浮点值。表达式将此数字转换为更有用的整数。

清单1给出了应用程序的源代码Guess

清单1. Guess.java
class Guess
{
   public static void main(String[] args) throws Exception
   {
      outer:
      while (true)
      {
         System.out.println("I'm thinking of a number between 0 and 9.");
         int number = (int) (Math.random() * 10);
         while (true)
         {
            int guessNumber;
            while (true)
            {
               System.out.println("Enter your guess number between 0 and 9.");
               guessNumber = System.in.read();
               while (System.in.read() != '\n');
               if (guessNumber >= '0' && guessNumber <= '9')
               {
                  guessNumber -= '0';
                  break;
               }
            }
            if (guessNumber < number)
               System.out.println("Your guess is too low.");
            else
            if (guessNumber > number)
               System.out.println("Your guess is too high.");
            else
            {
               System.out.println("Congratulations! You guessed correctly.");
               while (true)
               {
                  System.out.println("Press n for new game or q to quit.");
                  int ch = System.in.read();
                  while (System.in.read() != '\n');
                  if (ch == 'n')
                     continue outer;
                  if (ch == 'q')
                     break outer;
               }
            }
         }
      }
   }
}

Guess展示了前面的文章中提出的几个陈述和其他基本特征。该main()方法提供一个while语句,生成一个新的数字,并给你一个机会去猜测它。表达(int) (Math.random() * 10)乘以random()10的返回值的范围内变化,以0.0至几乎10.0,并将结果转换为整数,从0到9的范围内。

需要括号

圆括号Math.random() * 10是必要的,因为cast运算符[ (int)]的优先级高于乘法(*)。在没有圆括号的情况下,random()返回值将被转换为整数,这将始终为0.将0乘以10将得到0,这将始终分配给number。产生的游戏将是相当无聊。

生成数字后,main()执行一个内部while语句来处理所有的猜测。它反复提示猜测,将按下的键的Unicode字符值转换为从0到9的二进制整数值,并确定用户是否正确猜测。输出合适的消息。正确猜测的用户有机会通过按n下来播放新游戏,或按下退出应用程序q

源代码的一个有趣的部分是while (System.in.read() != '\n');。我使用这个语句\r\n从操作系统的键盘缓冲区中刷新行分隔符(例如,在Windows上)。如果我不这样做,您将看到多个提示,因为每个分隔符字符将被解释为尝试输入从0到9(或n或q)的值。如果你在一个旧版本的Mac OS的运行Java,你可能不得不更换\n\r,这是Mac的行分隔符。在Linux或Unix上运行时,无需进行任何更改,其行分隔符为\n。(你可以通过使用标准类库的System类来提供代码的可移植性,line.separator我们将把这个任务作为未来的练习,当你对Java的类和方法更熟悉时)。

编译清单1如下:

javac Guess.java

然后运行应用程序:

java Guess

以下是样品运行的输出:

I'm thinking of a number between 0 and 9.
Enter your guess number between 0 and 9.
5
Your guess is too high.
Enter your guess number between 0 and 9.
2
Your guess is too low.
Enter your guess number between 0 and 9.
3
Your guess is too low.
Enter your guess number between 0 and 9.
4
Congratulations! You guessed correctly.
Press n for new game or q to quit.
q

结论是

语句是Java应用程序的主体。掌握它们与其他基本语言功能将帮助您开发一个坚实的基础,在其上建立您更高级的语言功能的知识。我们将在下一篇文章中开始这个扩展,在这篇文章中,我将向您介绍Java类和对象。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值