Chapter 5: Conditionals and Loops

Version 5.11

DRAFT: needs proofreading and material on array lists.

Two class days

Handouts: none

Plan

First, we'll look at conditionals. Then we'll skip ahead into the graphics section to see how conditionals can be applied in GUIs. Finally, we'll come back to look at loops.

First Day

(5.1) Boolean expressions

(5.2) The if statement

  1. The simple if statement (no else)

  2. The if-else statement

  3. Blocking. So, if indentation does not suffice to place a sequence of statements, what does work? A block of statements.

  4. Nested if statements

(5.3) Comparing data

Comparing floating point numbers: == requires exact equality, but floating point operations are inexact, so we usually want to find whether |ab| < tolerance.

Comparing characters: the Unicode character set determines the ordering of characters.

Comparing Strings:

(5.7) Determining event sources

A single listener can listen for events from more than one object. In that case, we might want to determine which object emitted the event. Use the ActionEvent method getSource, which returns a reference to the emitting object.

Listings 5.12–5.13: LeftRight, LeftRightPanel

Two buttons with a single action listener.

Note the subpanel used for grouping; but why is the arrangement of label and subpanel vertical? Because of the size of the outer panel — as you can see by expanding it.

(5.8) Check Boxes and Radio Buttons

Check boxes are square buttons that can be independently toggled (checked or unchecked). When their state changes, they generate an ItemEvent, which may be passed to an ItemListener. The listener typically doesn't ask the event source; rather it queries the state of each of the checkboxes that it serves.

Listings 5.14–5.15 StyleOptions, StyleOptionsPanel

These illustrate using two checkboxes to select italic and/or bold fonts. It also shows the Font class, representing a character font. If both are checked, the font is set to Font.ITALIC + Font.BOLD, representing the combination of italic bold.

Radio buttons are used in groups, called ButtonGroups. They can be toggled on and off; but unlike checkboxes, they are mutually exclusive; i.e., within a ButtonGroup, only one JRadioButton can be on at a time. A radio button generates an ActionEvent which it is turned on, but not when it is turned off, and the listener probably wants to determine the event source.

Listings 5.16–5.17 QuoteOptions, QuoteOptionsPanel

These use three radio buttons to choose the type of quotation displayed. Note the use of a ButtonGroup and adding each radio button to the group.

(5.4) The while statement

Provides controlled repetition of statements (iteration). We use the word iteration to mean either (1) the process of repeating a statement; or (2) a single repetition of a statement. E.g.:

Syntax:

while (expr)
  statement;

Operation: as long as expr is true, keep executing statement (which can be and usually is a block statement).

Listing 5.7 Average

Uses a while loop and a sentinel value to indicate end of input; uses priming read before loop and reads next value just at end of loop before next iteration. Also uses an accumulator (running sum).

Listing 5.8 WinPercentage

Uses while loop to validate input.

Infinite loops occur if the expr never becomes false. The programmer must ensure that statement makes expr eventually become false. Be prepared to interrupt; in Unix, you can use C-c (control-C) to interrupt.

Nested loops are loops within loops.

Nested loops example:

int line = 1;
while (line < 5) {
  char letter = 'a';
  while (letter < 'f') {
    System.out.print(letter);
    letter++;
  }
  System.out.println(); // why?
  line++;
}

Listing 5.9 PalindromeTester

Outer loop reads each line of input; inner loop compares characters forwards from beginning of line and backwards from end of line to middle. Note how the values of left and right are updated. (This program is not sophisticated enough to allow for differences of spacing, capitalization, or punctuation.)

Using the break or continue statement in a while statement is possible, but should be avoided, because it makes a less clearly structured program.

Why is this wrong for the empty string?

Second Day

(5.5) Iterators

An Iterator is an object that allows us to iterate through a sequence of data — usually a collection, such as a list — so that we process each element in turn.

Iterators must have these methods:

Using an Iterator (Example)

(Assume c is some type of collection)

Iterator citer = c.iterator();
while (citer.hasNext()) {
  Object thing = citer.next();
  // process thing ...
}

Scanners are iterators, but they also define some more specialized methods such as hasNextDouble and nextDouble.

Listing 5.10 URLDissector.java

Uses nested loops, with a Scanner as iterator for each loop.

(5.6) Array Lists

The class java.util.ArrayList provides dynamically resizable lists implemented as arrays; we'll explore the array data type in Chapter 8.
As with strings, we can refer to the elements by index. Unlike strings, we can insert and remove elements. An ArrayList can expand as data are added and shrink when they are deleted.

Figure 5.8 lists some of the important methods of ArrayList: constructor/0, add(object), add(index, object), clear, remove(index), get(index), set(index, object), indexOf(object), contains(object), isEmpty(), size().

The constructor is specified as ArrayList<E>() — but what is E? E is the type of objects we want the list to contain.

It seems that DrJava Interactions will let us get away with some things that the Java compiler will not:

Welcome to DrJava.  ...
> import java.util.ArrayList;
> ArrayList al = new ArrayList<String>();
> ArrayList as = new ArrayList<String>();
> ArrayList ai = new ArrayList<Integer>();
> as
[]
> ai
[]
> as.add("Cats")
true
> as.add("Dogs")
true
> as
[Cats, Dogs]
> as.set(1, "Mice")
"Dogs"
> as
[Cats, Mice]
> as.add(32)
true
> as
[Cats, Mice, 32]
> ArrayList<String> as = new ArrayList<String>();
> ArrayList<Integer> ai = new ArrayList<Integer>();
> ai.add("Horse")
Static Error: No method in ArrayList<Integer> with name 'add' matches this invocation
    Arguments: (String)
    Candidate signatures: 
        boolean add(Integer)
        void add(int, Integer)
> as.add(32)
Static Error: No method in ArrayList<String> with name 'add' matches this invocation
    Arguments: (int)
    Candidate signatures: 
        boolean add(String)
        void add(int, String)
> ai.add(32)
true
> ai.add(96);
> ai.add(37);
> ai
[32, 96, 37]
> ai.get(0)
32
> ai.set(0, 19)
32
> ai
[19, 96, 37]
> ai.isEmpty()
false
> as.isEmpty()
true
> ai.size()
3
> as.size()
0
> ai.contains(32)
false
> ai.contains(96)
true
> ai
[19, 96, 37]
> ai.indexOf(96)
1
> ai.remove(2)
37
> ai
[19, 96]
> ai.clear
Static Error: No field in ArrayList<Integer> has name 'clear'
> ai.clear()
> ai
[]
> ArrayList ax = new ArrayList()
> ax
[]
> as.add(10)
Static Error: No method in ArrayList<String> with name 'add' matches this invocation
    Arguments: (int)
    Candidate signatures: 
        boolean add(String)
        void add(int, String)
> ax.add(10)
true
> ax.add("Horse")
true
> ax
[10, Horse]
> ArrayList<Short> ay = new ArrayList()
Static Error: Bad types in assignment: from raw ArrayList to ArrayList<Short>
> ArrayList<Short> ay = new ArrayList<Short>()
> ArrayList ag = ay;
> ay.add("Metaphor")
Static Error: No method in ArrayList<Short> with name 'add' matches this invocation
    Arguments: (String)
    Candidate signatures: 
        boolean add(Short)
        void add(int, Short)
> ag.add("Hypothesis")
true
> ay
[Hypothesis]
> ag
[Hypothesis]
> 

Listing 5.11 Beatles: uses an ArrayList to store the names of the famous musicians. Demonstrates constructor, add, indexOf, remove, add, get, and toString.

This is our first encounter with the Java Collections Framework. In general, collections can store elements of any reference type. The default element type is Object. Using the new feature (Java 1.5) called generic types, we can specify that the element type is something more specific, e.g.,

ArrayList<Musician> band = new ArrayList<Musician>();

This has two advantages:

  1. stricter type checking for elements put into the collection;
  2. eliminates the need for cast when retrieving elements, e.g., (Musician) band.get(0)

    —On the other hand, it can make code quite a lot more complicated sometimes!

    Example: a band as an ArrayList of Musicians (i.e., containing only Musicians):

    1. without generic types:
        // creation and storage
        ArrayList band = new ArrayList();
        band.add(new Musician("J. S. Bach"));
        band.add(new String("abc")); // oops! undetected error
    
        // retrieval
        Object obj = band.get(0);
        if (obj instanceof Musician) {
    
    Musician mus = (Musician) obj; ... } else // report an error!!
    
    1. with generic types:
        // creation and storage
        ArrayList<Musician> band = new ArrayList<Musician>();
        band.add(new Musician("J. S. Bach"));
        band.add(new String("abc")); // error detected at compile time
    
        // retrieval
        Musician mus = band.get(0);
    

ArrayList Efficiency

Discussion of the (in)efficiency of insert and delete far from the rear of the list, and of expanding and contracting the array.

Exercises, pp. 287 ff. [NEEDS REVISION]


  1. Version log:
    • Version 5.1, 2012 Feb 7. Added ArrayLists (from old chapter 7).
    • Version 5.0, 2012 Feb 2. Split chapter 5 into chapters 5 and 6.
    • Version 4.1, 2011 Feb 11. Converted to markdown.
    • Version 4, 2010 Feb 5. Converted to RST.
    • Version 3, 2009 Feb 16. Added new examples.
    • Version 2, 2009 Feb 10. Updated for 6th edition.