Solutions for Exercise 3

Here, we propose solutions to the third exercise. Other solutions can also be correct, but these are the ones that can be expected. All the solutions together, can be downloaded as counterProgramSolutions.zip.

      
  1. Hopefully this is by now a fairly simple task:
    public static boolean contains (int elem, int[] a) {
         for (int i = 0; i < a.length; i ++)
             if (a [i] == elem) return true;
         return false;
    }
    

    We go through the array a and as soon as we find a number that is equal to elem, we return true without looking further in the array. If we have gone through the entire for-loop without return, then it means that the elem does not exist and we can return false.

  2. We have the following class of for counters:
    public class SimpleCounter implements Counter {
    
         private int value;
    
         public SimpleCounter() {
             value = 0;
         }
    
         public void count() {value ++;}
         public void reset() {value = 0;}
         public int getValue() {return value;}
    }
    

    We have a single instance variable value of type int. The three methods modify or return this variable. The constructor sets the initial value to zero.

  3. After the first three lines in the main method, the memory looks as below:

    After that, calling the method changeValues. It first creates local variables for the three parameters n c1 and c2 and the values of the arguments in the call are copied to these variables. Now before the body of the method is executed, the situation is like this:

    n and k both have the value 5, but this value is stored separately in each memory cell. a and c1 refer to the same counter objects. The same applies for b and c2.

    After the statements in changeValues, but before we return from the method, the situation like this:

    n is increased by one, which does not affect k. The method count() is called for c1 once, so that the counter state variable has been incremented. a refers to the same object so the change is visible even after the return. c2 points to a new counter whose method count is also called once but this doesn't change the counter pointed by b.

    Finally, we return to the main method and the local variables from the subroutine disappear:

    The counter to which c2 pointed is now forgotten and will be recovered by the garbage collector. Finally, the program prints:

    k = 5
    a = 1
    b = 0
    
  4. counterProgramSolutions.zip
  5. With an additional constructor SimpleCounter becomes:
    public class SimpleCounter implements Counter {
    
         private int value;
    
         public SimpleCounter() {
             value = 0;
         }
    
         public SimpleCounter(int init) {
             value = init;
         }
    
         public void count() {value ++;}
         public void reset() {value = 0;}
         public int getValue() {return value;}
    }
    

    The main method in simpleCounter/Main.java should be changed as:

    Counter ctr = new SimpleCounter(95);
    

    to get a counter whose initial value is 95 instead of zero.

    Note here that the type of the ctr is specified as Counter, i.e. the interface. When we create the object, we have an instance of the class SimpleCounter, which implements this interface.

  6. class BoundedCounter is
    public class BoundedCounter implements Counter {
    
         private int value;
         private int modulus;
    
         Public BoundedCounter (int init, int modulus) {
             this.value = init;
             this.modulus = modulus;
         }
    
         public void count () {
             value = (value + 1) % modulus;
         }
    
         public void reset () {value = 0;}
    
         public int getValue () {return value;}
    }
    

    We must save modulus as an instance variable. Besides we change the count method to count modulus modulus.

    Note: An alternative definition of the count is

    public void count () {
         if (value == modulus-1)
             value = 0;
         else
             value++;
    }
    
  7. The class ChainedCounter is
    public class ChainedCounter implements Counter {
    
         private int value;
         private int modulus;
         private Counter next;
    
         public ChainedCounter(int init, int modulus,
                               Counter next) {
             this.value = init;
             this.modulus = modulus;
             this.next = next;
         }
    
         public void count () {
             value = (value + 1) % modulus;
             if (value == 0 && next! = null) next.count ();
         }
    
         public void reset () {value = 0;}
    
         public int getValue () {return value;}
    }
    

    The difference from a BoundedCounter is that here we also have a reference to another Counter. In the Clock application, we have three counters connected like this:

    The program calls secsCounter.count() once a second (in ClockPanel.java, a listener is registered with the timer). This means that the second counter is updated with the correct frequency; each time the counter reaches 60 seconds and start again from zero, this invokes the minute counter count(). Similarly the minutes counter invokes the hours counter once an hour. When midnight comes, however, then there is no counting of anything, because the next variable in the counter for hours is null.