Before you begin

This unit is part of the “Intro to Java programming” learning path. Although the concepts discussed in the individual units are standalone in nature, the hands-on component builds as you progress through the units, and I recommend that you review the prerequisites, setup, and unit details before proceeding.

Unit objectives

  • Understand the purpose of a loop
  • Use correct syntax for for, while. and dowhile statements
  • Know how to break out of a loop, or skip a loop interation and then continue

Loops defined

Sometimes you want your code to do the same thing over and over again until the job is done. You can use a loop for this purpose. A loop is a programming construct that executes repeatedly while a specific condition (or set of conditions) is met. For instance, you might ask a program to read all records until the end of a data file, or to process each element of an array in turn. (You’ll learn about arrays in the next unit.)

Three loop constructs make it possible to iterate over code or execute it more than once:

  • for loops
  • while loops
  • dowhile loops

for loops

The basic loop construct in the Java language is the for statement. You can use a for statement to iterate over a range of values to determine how many times to execute a loop. The abstract syntax for a for loop is:



for (initialization; loopWhileTrue; executeAtBottomOfEachLoop) {
  statementsToExecute
}

At the beginning of the loop, the initialization statement is executed (multiple initialization statements can be separated by commas). Provided that loopWhileTrueloopWhileTrue (a Java conditional expression that must evaluate to either true or false) is true, the loop executes. At the bottom of the loop, executeAtBottomOfEachLoopexecuteAtBottomOfEachLoop executes.

For example, if you wanted the code in the main() method in Listing 1 to execute three times, you can use a for loop

Listing 1. A for loop

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

The local variable aa is initialized to zero at the beginning of Listing 1. This statement executes only once, when the loop is initialized. The loop then continues three times, and each time aa is incremented by one.

You’ll see in the next unit that an alternative for loop syntax is available for looping over constructs that implement the Iterable interface (such as arrays and other Java utility classes). For now, just note the use of the for loop syntax in Listing 1.

while loops

The syntax for a while loop is:


while (condition) {
  statementsToExecute
}

As you might suspect, if condition evaluates to true, the loop executes. At the top of each iteration (that is, before any statements execute), the condition is evaluated. If the condition evaluates to true, the loop executes. So it’s possible that a while loop will never execute if its conditional expression is not true at least once.

Look again at the for loop in Listing 1. For comparison, Listing 2 uses a while loop to obtain the same result.

Listing 2. A while loop

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

As you can see, a while loop requires a bit more housekeeping than a for loop. You must initialize the aa variable and also remember to increment it at the bottom of the loop.

do…while loops

If you want a loop that always executes once and then checks its conditional expression, you can use a do...while loop, as shown in Listing 3.

Listing 3. A do…while loop
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);

The conditional expression (aa < 3) is not checked until the end of the loop.

Loop termination

At times, you need to bail out of — or terminate— a loop before the conditional expression evaluates to false. This situation can occur if you’re searching an array of Strings for a particular value, and once you find it, you don’t care about the other elements of the array. For the times when you want to bail, the Java language provides the break statement, shown in Listing 4.

Listing 4. A break statement

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

The break statement takes you to the next executable statement outside of the loop in which it’s located.

Loop continuation

In the (simplistic) example in Listing 4, you want to execute the loop only once and then bail. You can also skip a single iteration of a loop but continue executing the loop. For that purpose, you need the continue statement, shown in Listing 5.

Listing 5. A continue statement

public static void main(String[] args) {
  Logger l = Logger.getLogger(Person.class.getName());
  int aa = 0;
  while (aa < 3) {
    aa++;
    if (aa == 2)
      continue;
    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());
  }
}

In Listing 5, you skip the second iteration of a loop but continue to the third. continue comes in handy when you are, say, processing records and come across a record you don’t want to process. You can skip that record and move on to the next one.

Test your understanding

  1. In Unit 7, you saw the concat() method used to illustrate method chaining in the implementation of getName(). Implement the getName() method using string concatenation (with the + operator). Write a JUnit test to ensure that the result is as you expect.

  2. Which operator(s) are binary operators?

    1. ++
    2. +
    3. %
    4. --
    5. +=
    6. a, b, and d
    7. b, c, and e
    8. None of the above
  3. String concatenation means combining the contents of two or more strings to make a single, larger string.

    1. True
    2. False
  4. Which of the following means “if a is less than or equal to b”?

    1. if (a lt b)
    2. if (b < a)
    3. if (b +< a)
    4. if (a <= b)
    5. None of the above
  5. What is the value of variable c after execution of the following block? Explain your answer.

    
       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. Will the following code compile? Explain your answer.

    
       public int method2() {
          int a = 0;
          
          if (a > 0) {
             int b = a;
          }
          
          int c = b;
          
          return c;
       }
    

  7. What is the value of variable c after execution of the following block? Explain your answer.

    
       public boolean method3() {
          boolean a = true;
          boolean b = false;
          boolean c;
          
          if (a = b) 
             c = false;
          else
             c = a;
          
          return c;
       }
    

  8. A for loop always executes at least once.

    1. True
    2. False
  9. The condition that determines whether or not a do...while loop continues is checked at the bottom of the loop.

    1. True
    2. False
  10. Write a method that contains a for loop that starts at 3, loops six times, and outputs the iteration number (1-based), along with the current loop variable using a JDK Logger. Use Listing 1 as an example of how to use Logger. Verify the results using your Logger output.

  11. Repeat the exercise in Question 10 with a different method name, but instead use a while loop. Verify the results using your Logger output.

  12. Repeat the exercise in Question 10 using a do...while loop. Verify the results using your Logger output.

  13. Write a method that contains a for loop that starts at zero (0), loops ten (10) times, and outputs the iteration number (1-based), along with the current loop variable using a JDK Logger class. Skip iterations 4, 5, and 9. Verify the results using your Logger output.

Check your answers

  1. In Unit 7, you saw the concat() method used to illustrate method chaining in the implementation of getName(). Implement the getName() method using string concatenation (with the + operator). Write a JUnit test to ensure that the result is as you expect.

     package com.makotojava.intro.unit7;
    
     import java.util.logging.Logger;
    
     public class Person {
    
        Logger l = Logger.getLogger(Person.class.getName());
    
        //private String name;
        private String lastName;
        private String firstName;
        private int age;
        private int height;
        private int weight;
        private String eyeColor;
        private String gender;
    
        public Person(String firstName, String lastName, int age, int height, int weight, String eyeColor, String gender) {
           this.firstName = firstName;
           this.lastName = lastName;
           this.age = age;
           this.height = height;
           this.weight = weight;
           this.eyeColor = eyeColor;
           this.gender = gender;
        }
    
        // This is a "derived" method. That is, there is no 1:1 mapping between it and
        /// an attribute.
        public String getFullName() {
           return getFirstName() + " " + getLastName();
        }
    
        public String getLastName() {
           return lastName;
        }
    
        public void setLastName(String lastName) {
           this.lastName = lastName;
        }
    
        public String getFirstName() {
           return firstName;
        }
    
        public void setFirstName(String firstName) {
           this.firstName = firstName;
        }   public int getAge() {
           return age;
        }
        public void setAge(int age) {
           this.age = age;
        }
        public int getHeight() {
           return height;
        }
        public void setHeight(int height) {
           this.height = height;
        }
        public int getWeight() {
           return weight;
        }
        public void setWeight(int weight) {
           this.weight = weight;
        }
        public String getEyeColor() {
           return eyeColor;
        }
        public void setEyeColor(String eyeColor) {
           this.eyeColor = eyeColor;
        }
        public String getGender() {
           return gender;
        }
        public void setGender(String gender) {
           this.gender = gender;
        }
    
        public String toString() {
           String ret = "Full Name: " + getFullName() + ", " +
                   "Height: " + getHeight() + ", " +
                   "Weight: " + getWeight() + ", " +
                   "Eye Color: " + getEyeColor() + ", " +
                   "Gender: " + getGender();
    
                return ret;
        }
    
     }
    

    JUnit test:

     package com.makotojava.intro.unit7;
    
     import static org.junit.Assert.assertEquals;
    
     import org.junit.Test;
    
     public class PersonTest {
    
        @Test
        public void testGetFullName() {
           // Note: use of new constructor with first and last name parameters
           Person p = new Person("John", "Doe", 24, 180, 78, "Blue", "MALE");
    
           String fullName = p.getFullName();
    
           assertEquals("John Doe", fullName);
        }
    
     }
    
  2. Which operator(s) are binary operators?

    1. ++
    2. +
    3. %
    4. --
    5. +=
    6. a, b, and d
    7. b, c, and e
    8. None of the above
  3. String concatenation means combining the contents of two or more strings to make a single, larger string.

    1. True
    2. False
  4. Which of the following means “if a is less than or equal to b”?

    1. if (a lt b)
    2. if (b < a)
    3. if (b +< a)
    4. if (a <= b)
    5. None of the above
  5. What is the value of variable c after execution of the following block? Explain your answer.

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

    Answer: c == 0. The line in bold appears to be part of the block that is executed if the condition in the first if were to evaluate to true, but it is not. It is merely indented, and thus executed every time. Since b is now -47, the condition in the following if evaluates to false. The variable c is never changed from its original assigned value of zero, and the return value of the method is therefore zero.

  6. Will the following code compile? Explain your answer.

    
       public int method2() {
          int a = 0;
          
          if (a > 0) {
             int b = a;
          }
          
          int c = b;
          
          return c;
       }
    

    Answer: No, the code will not compile. Variable b is declared within a block that goes out of scope on the next line. When b is then referenced to assign it to variable c it is out of scope, and the compiler will generate an error message.

  7. What is the value of variable c after execution of the following block? Explain your answer.

    
       public boolean method3() {
          boolean a = true;
          boolean b = false;
          boolean c;
          
          if (a = b) 
             c = false;
          else
             c = a;
          
          return c;
       }
    

    Answer: The return value is false. In the if block, it appears that a is compared to b, when in fact, b is assigned to a. A boolean assignment such as this always returns true, so the assignment of false to variable c occurs. The correct code on the highlighted line should be if (a == b).

  8. A for loop always executes at least once.

    1. True
    2. False
  9. The condition that determines whether or not a do...while loop continues is checked at the bottom of the loop.

    1. True
    2. False
  10. Write a method that contains a for loop that starts at 3, loops six times, and outputs the iteration number (1-based), along with the current loop variable using a JDK Logger. Use Listing 1 as an example of how to use Logger. Verify the results using your Logger output.

    public class Unit9 {
       private static final Logger log = Logger.getLogger(Unit9.class.getName());
    
       public void problem10() {
          for (int aa = 3, iterationNumber = 1; iterationNumber <= 6; aa++, iterationNumber++) {
             log.info("Iteration# " + iterationNumber + ", Loop variable: " + aa);
          }
       }
    }
    
  11. Repeat the exercise in Question 10 with a different method name, but instead use a while loop. Verify the results using your Logger output.

    public class Unit9 {
      private static final Logger log = Logger.getLogger(Unit9.class.getName());
    
      public void problem11() {
        int aa = 3;
        int iterationNumber = 1;
    
        while (iterationNumber <= 6) {
          log.info("Iteration# " + iterationNumber + ", Loop variable: " + aa);
          aa++;
          iterationNumber++;
        }
      }
    }
    
  12. Repeat the exercise in Question 10 using a do...while loop. Verify the results using your Logger output.

    public class Unit9 {
      private static final Logger log = Logger.getLogger(Unit9.class.getName());
    
      public void problem12() {
        int aa = 3;
        int iterationNumber = 1;
    
        do {
         log.info("Iteration# " + iterationNumber + ", Loop variable: " + aa);
         aa++;
         iterationNumber++;
        } while (iterationNumber <=6);
      }
    }
    
  13. Write a method that contains a for loop that starts at zero (0), loops ten (10) times, and outputs the iteration number (1-based), along with the current loop variable using a JDK Logger class. Skip iterations 4, 5, and 9. Verify the results using your Logger output.

    public class Unit9 {
      private static final Logger log = Logger.getLogger(Unit9.class.getName());
    
      public void problem13() {
        for (int aa = 0, iterationNumber = 1; aa < 10; aa++, iterationNumber++) {
          if (iterationNumber == 4 || iterationNumber == 5 || iterationNumber == 9) {
            log.info("Iteration# " + iterationNumber + " **SKIPPED**");
            continue;
         }
         log.info("Iteration# " + iterationNumber + ", Loop variable: " + aa);
        }
      }
    }
    

    JUnit Test – Unit9Test.java:

    package com.makotogo.learn;
    
    import org.junit.Test;
    
    public class Unit9Test {
    
      @Test
      public void testProblem10() {
        Unit9 testclass = new Unit9();
    
        testclass.problem10();
      }
    
      @Test
      public void testProblem11() {
        Unit9 testclass = new Unit9();
    
        testclass.problem11();
         }
    
      @Test
      public void testProblem12() {
        Unit9 testclass = new Unit9();
    
        testclass.problem12();
         }
    
      @Test
      public void testProblem13() {
        Unit9 testclass = new Unit9();
    
        testclass.problem13();
         }
    
    }
    

Previous: Conditional operators and control statementsNext: Java Collections