RU beehive logo ITEC dept promo banner
ITEC 120
2009spring
ibarland
nokie
jmdymacek

homeinfolectslabsexamshws
textbooktutor/PIsjava.lang docsjava.util docs

lect09c
Introducing `while`

We have seen and if-else statements, which are kinda neat: they have the computer decide whether or to do one thing or another.
We have also seen the notion of calling helper methods, which is also neat: if we have a ten-line helper method which we call five times, the computer runs fifty lines of code even though we only wrote fifteen!
Today, we'll take this further, with loops: we'll have the computer decide how many times to repeat a chunk of code.

We'll start with an example that doesn't actually do anything, and build up to more and more useful programs using loops.

Suppose we had some existing code, which just printed some messages to the console window.

  void printHolidayMsgs() 
  {
    System.out.println( "Day 1 of Christmas" );
    System.out.println( "Day 2 of Christmas" );
    System.out.println( "Day 3 of Christmas" );
  }
Your job is to extend this to work for 12 days. You can see that cut-and-paste will do most of your work, but you still have to manually change the number in each of twelve lines. And what if your boss got carried away with holiday spirit, and wanted to celebrate 31 days, or 365 days? It rapidly becomes tedious (and error-prone) to change the day-number in our program.

Can't we get the computer to increase the day by one, each time? Yes! A clever friend comes up with this version, where you only need to cut/paste, and no thinking/updating is needed!

  void printHolidayMsgs() 
  {
    int i = 1;

    System.out.println( "Day " + i " of Christmas" );
    i = i+1;
    System.out.println( "Day " + i " of Christmas" );
    i = i+1;
    System.out.println( "Day " + i " of Christmas" );
    i = i+1;
  }
It's important that no thinking is needed, because no thinking is exactly what a computer is good at. It turns out, once we have the exact same two lines of code repeated, we can use a while-loop, to tell the computer how long to keep repeating those two lines:
  void printHolidayMsgs() 
  {
    int i = 1;

    while (i < 3)
    {
      System.out.println( "Day " + i " of Christmas" );
      i = i+1;
    }
  }

You can use this strategy when writing loops: As a first attempt, think of how to write the program where you could cut/paste many times, but can't change a single bit except for cutting/pasting. This part will become your “loop body”.

Question: What is true, after the loop finishes? That is — what is the value of i?

A second example

Suppose we have a RoachPopulation. Most people don't notice a RoachPopulation until it grows to 1000 — then they start to do something about it. Let's think about writing a method which repeatedly grows a population until it's 1000 or bigger:

class RoachPopulation 
  {
  // ... other methods and fields ...

  public void growTilBig() 
  {
     if (this.getPopulation() <= 1000) 
     {
       this.breed();
     }

     if (this.getPopulation() <= 1000) 
     {
       this.breed();
     }

     if (this.getPopulation() <= 1000) 
     {
       this.breed();
     }

     if (this.getPopulation() <= 1000) 
     {
       this.breed();
     }
   }



  public double void breed() 
  {
    this.pop = 2*this.pop;
  }


  public long getPopulation() {
    return this.pop;
  }

  private long pop = 1;

}
Hmm, this only works if four or fewer generations will bring us there. What if it takes longer? (What else should we fix about this code, btw? It has a magic number!)

If we want to keep doing something over and over and over, rather than cut-and-paste, we can use a while loop:

  void growTilBig() 
  {
     final INFESTATION_THRESHOLD = 1000;
     while (this.getPopulation() <= INFESTATION_THRESHOLD) 
     {
       this.breed();
     }
   }
We say that this.getPopulation() <= INFESTATION_THRESHOLD is the loop's condition, and this.breed(); is the loop's body.

Question: What is true, after the loop finishes? That is — what is the value of i?

Variant: What if we want to know how many generations it takes to reach an infestation level?
Solution: First, think about how you'd (try to) do this without a loop:

  int generationsTilBig() {
     int numGens = 0;
     if (this.getPopulation() <= INFESTATION_THRESHOLD) {
       this.breed();
       numGens = numGens + 1;
       }
     if (this.getPopulation() <= INFESTATION_THRESHOLD) {
       this.breed();
       numGens = numGens + 1;
       }
     if (this.getPopulation() <= INFESTATION_THRESHOLD) {
       this.breed();
       numGens = numGens + 1;
       }
     if (this.getPopulation() <= INFESTATION_THRESHOLD) {
       this.breed();
       numGens = numGens + 1;
       }
     if (this.getPopulation() <= INFESTATION_THRESHOLD) {
       this.breed();
       numGens = numGens + 1;
       }
     if (this.getPopulation() <= INFESTATION_THRESHOLD) {
       this.breed();
       numGens = numGens + 1;
       }
     return numGens;
     }
This gives us the idea of how our while loop should look:
  int generationsTilBig() {
     int numGens = 0;
     while (this.getPopulation() <= INFESTATION_THRESHOLD) {
       this.breed();
       numGens = numGens + 1;
       }
     return numGens;
     }
We call numGens a “accumulator variable”, because it accumulates information as we continue processing. (More precisely: it captures all the information1 we need to remember about past processing.)
tip: When writing a loop, first figure out the body — that is, what action do you want to do, over and over and over?
tip: When writing the condition for a loop, explain to yourself why you are sure this loop will eventually finish. Hey — now that I think about it, these above loops aren't guaranteed to finish; sometimes they might run forever: an infinite loop. When, exactly, does that happen? How to fix it? (Or should it even be fixed, in this case?)
tip (BlueJ): You recognize an infinite loop by the fact that your IDE stops responding. In BlueJ, you'll see the progress bar (underneath the compile button) churning away like a red and white barber pole (see image on left). You can halt your program by right-clicking on that progress bar (see image on right):


Practice: I want a method for BankAccounts which keeps making a $5 deposit until the balance is more than $500. (Not bad!)
Question: are you sure this loop will always finish?
(What if there might be penalties for excessive deposits?!)


1 To be really technical: information from “past processing” also involves the mutation to the population field. In fact, this method is arguably poor style, since it both returns a value and updates the state of the RoachPopulation object.      

homeinfolectslabsexamshws
textbooktutor/PIsjava.lang docsjava.util docs


©2009, Ian Barland, Radford University
Last modified 2009.Mar.27 (Fri)
Please mail any suggestions
(incl. typos, broken links)
to iba�rlandrad�ford.edu
Powered by PLT Scheme