Java Language Basics

Java 101: Deciding and iterating with Java statements

Do you want to loop, switch, or take a break? Learn how to use standby statements like for, while, if-else, and break, then get started with the new switch expressions in Java 12

1 2 3 Page 2
Page 2 of 3

In this case, the output would be odd because i % 2 yields 1, which matches the second case label. If we omitted break;, and if the number was even, the output would be even followed by odd, because execution would drop through to the second case.

Switching case

Sometimes, it's desirable to have execution drop through to the next case. For example, suppose you wanted to execute common code in response to the user specifying an uppercase or lowercase command-line option letter:

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

   // ...

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

Imagine that a for statement (discussed shortly) is iterating over each of the arguments in the array of command-line arguments passed to an application's main() method. If the argument is -v (dash and lowercase v) or -V (dash and uppercase V), the application's version number is output. When -v is specified, it's necessary to have execution drop through to the following case, which outputs the version number when -V is specified.

The default case is executed whenever the string referenced by args[i] doesn't match any of the case labels. In other words, the user has specified an unknown option.

Switch expressions in Java 12

Java SE 12 introduced switch expressions as an enhancement to the switch statement. Think of a switch expression as a kind of multiway conditional operator (?:). Switch expressions are intended to simplify coding and to prepare for pattern matching in Java.

The switch expressions feature is currently available as a preview language feature, so that developers can try it out and offer feedback. As of this writing, you need a special command-line option to access it. Since there's no guarantee that switch expressions will remain in future version of Java, I'll just present a simple example using jshell.

Start jshell with the --enable-preview option, as follows:


jshell --enable-preview

At the jshell> prompt, enter the following enumerated type (you'll learn about enumerated types later in this series):


jshell> enum Coin { PENNY, NICKEL, DIME, QUARTER }
|  created enum Coin

Continue by entering the following snippet at the jshell> prompt:


jshell> var coin = Coin.DIME
coin ==> DIME

jshell> var value = switch(coin) {
   ...> case PENNY -> 1;
   ...> case NICKEL -> 5;
   ...> case DIME -> 10;
   ...> case QUARTER -> 25;
   ...> }
value ==> 10

jshell>

In this example, we first introduce the coin variable initialized to Coin's DIME value. We then introduce a value variable that receives its value from a switch expression. This expression switches on coin and offers four cases. Each case returns the numeric value of the coin (e.g., 1 for PENNY). The semicolon terminator is required for each case. After entering the switch expression, jshell evaluates it and outputs the value (10) assigned to value.

See Dustin Marx's "JDK 12: Switch Statements/Expressions in Action" for more about switch expressions in Java 12.

Iterating and looping: for, while, and do-while

Iteration statements (also known as loop statements) repeatedly execute other statements for a specific number of iterations (loops) or indefinitely until some terminating condition arises. For example, as previously mentioned, you might want to iterate over all of the String objects in the array of command-line arguments passed to a main() method. Java supports the for, while, and do-while iteration statements.

The for statement and for loops in Java

The for statement executes another statement a specific number of times or indefinitely. It is essentially a compact form of the while statement (discussed later) and has the following syntax:


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

This example shows that a for statement begins with the reserved word for and continues with a parentheses-delimited and semicolon-separated sequence of three sections:

  • initialize: A comma-separated list of variable declarations or assignments. These variables, which are known as iteration variables or loop variables, are used to index arrays, take part in calculations, or perform other tasks.
  • test: A Boolean expression that determines how long the loop executes. Execution continues for as long as this expression remains true.
  • update: A comma-separated list of expressions that typically modify the loop variables.

Following the for statement is a statement to execute repeatedly.

Each of the three sections is optional. As a result, for can be shrunk down to for (; ;). Because there is no stopping condition, the resulting loop is known as an infinite loop.

The following example uses the for statement to iterate over all elements in an array named args, outputting the value of each array element:


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

This example works as follows:

  1. Declare variable i and initialize it to 0.
  2. Evaluate i < args.length. If i equals args.length, terminate the loop.
  3. Execute System.out.println(args[i]);.
  4. Execute i++.
  5. Continue with Step 2.

Variable i is visible to the for statement's test and update sections, and to statement. However, it isn't visible to subsequent statements. If you want subsequent statements to see i's final value, declare i before for, as follows:


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

The variable that controls the loop can be a different primitive type, such as Boolean, character, or double precision floating-point. Here are three examples:


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);

Finally, as previously mentioned, the initialize section can declare multiple variables. The following example declares two variables, incrementing one variable and decrementing the other variable throughout the loop:


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

The output consists of six lines of 5.

The while statement

The while statement repeatedly executes another statement while its controlling Boolean expression keeps evaluating to true. This statement has the following syntax:


while (Boolean expression)
   statement
   

This syntax shows that a while statement begins with the reserved word while and continues with a parenthesized Boolean expression. This statement is followed by another statement to execute repeatedly.

Here's an example of the while statement:


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

This example works as follows:

  1. Declare variable i and initialize it to 0.
  2. Evaluate i < args.length. If i equals args.length, terminate the loop.
  3. Execute System.out.println(args[i]);.
  4. Execute i++.
  5. Continue with Step 2.

This example is the while equivalent of the previous for example. You could compact the example to repeatedly execute a simple statement instead of a compound statement, as follows:


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

In this compacted example, we change the postincrement statement to an expression that's passed to the array index operator. Although the code is more compact, some might prefer the previous example for clarity.

The do-while statement

The do-while statement repeatedly executes a statement while its controlling Boolean expression, which is evaluated after the statement is executed, evaluates to true. This statement has the following syntax:


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

This syntax shows that a do-while statement begins with reserved word do, continues with a statement to execute repeatedly, and ends with the reserved word while, followed by a parenthesized Boolean expression.

The following example demonstrates the do-while statement:


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

This example works as follows:

  1. Declare int variable ch to store a character's numeric code.
  2. Prompt the user to press the x key to continue.
  3. Read a key code from the keyboard via System.in.read(), which is a companion of System.out.println(). Because this method returns the key's code as an int, assign this value to ch.
  4. Compare ch's value with 'x'. Note that 'x' is widened from char to int before the comparison. Terminate the loop when this expression evaluates to false (ch equals 'x'). Otherwise, continue with Step 2.

The difference between while and do-while is that while executes its statement zero or more times, whereas do-while executes its statement one or more times. You will choose either statement based on this property. For example, it's appropriate to use while to iterate over the args array because this array might have zero length and you don't want to access the array and raise an out-of-bounds exception. In contrast, you would access the array at least once with do-while. It's appropriate to use do-while to prompt the user to enter a key and read the response because these tasks must happen at least once.

Breaking and continuing: break and continue

You've seen the break statement used to break out of a switch statement after a case has executed. We can also use break statements as part of an iteration statement, along with continue statement. We'll explore both of these options.

Unlabeled and labeled break statements

The unlabeled break statement terminates a switch, for, while, or do-while statement by transferring execution to the first statement following this statement. Here it is by itself:


break;

Here's an unlabeled break statement in an iteration statement context:


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

Here we've introduced a for-based infinite loop that repeatedly prompts the user to press the x key and reads this key until it equals 'x'. An if statement performs the comparison, executing break; to terminate the loop when the x key is pressed.

The labeled break statement terminates a containing and labeled switch, for, while, or do-while statement by transferring execution to the first statement following the containing statement. It has the following syntax:


break label;

This syntax consists of reserved word break followed by a non-reserved word identifier to serve as a label, followed by a semicolon. The label must be prefixed to a previous switch or iteration statement and must be followed by a colon.

The following example demonstrates the labeled break statement in an iteration statement context:


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;
   }
}

This example presents a pair of nested infinite while loops that describe part of a number-guessing game. The outer loop is a stub for playing the game, whereas the inner loop prompts the user to play a new game or quit the game.

If the user presses the n key, the unlabeled break statement is executed to terminate the inner loop so that a new game can be played. If q is pressed, break outer; is executed to quit the outer loop, which is assigned an outer: label.

The unlabeled continue and labeled continue statements

The unlabeled continue statement skips the remainder of the current iteration and tells the iteration statement to advance to the next iteration. It has the following syntax:


continue;

Here's an example usage of the unlabeled continue statement:


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

This example's for statement iterates from -2 to 2, repeatedly executing an if-else statement and then incrementing i by 1 after each iteration.

To prevent a divide-by-zero exception when i contains 0, if tests i for 0. If this is the case, it executes continue;, which causes for to increment i and then evaluate i <= 2. Otherwise, 10 / i is evaluated and the result is output.

The labeled continue statement skips the remaining iterations of one or more nested iteration statements and transfers execution to the labeled iteration statement. It has the following syntax:


continue label;

This syntax consists of reserved word continue followed by a non-reserved word identifier to serve as a label, followed by a semicolon. The label must be prefixed to a previous iteration statement and must be followed by a colon.

Here's an example using the labeled continue statement:

1 2 3 Page 2
Page 2 of 3