25 Apr 2012 [ 201 week15 ]

The final exam will be comprehensive. It will focus on concepts covered in the last half of the semester, but there's not really any way to avoid all the earlier stuff.

Here are the main concepts from the first half (see also the exam 1 review):

The new concepts include:

You might want to review the following chapters in the book (chapter numbers might differ depending on the edition you're using):

Example exam problems

You'll be given information about any special classes and methods you need to know on the exam, but the questions below might not provide that information. For example, if you have to use an ArrayList on the exam, it will appear in a summary of useful classes, along with the methods you might have to use.

  1. Given the class NumberList outlined below that keeps track of a list of numbers, create a subclass that represents a list that you're only allowed to add non-negative numbers to (if you try to add a negative number, it's just ignored). You should override the add method appropriately.

    class NumberList {
        // Add a number to the list.
        void add(int x) {
            ...
        }
        // Get the number at entry i in the list.
        int get(int i) {
            ...
        }
        ...
    }
    
  2. Fill in the code below so that the program prints each unique number in the array at most once.

    class Processor {
        // Define instance variables and constructor ...
        // Define process(int value) method ...
    }
    
    class Printer {
        public static void main(String[] args) {
            int[] numbers = { 1, 2, 1, 1, 3, 2, 5, 5, ... };
            Processor p = new Processor();
            for (int x : numbers) {
                p.process(x);
            }
        }
    }
    
  3. What does the following code print?

    class Test {
        public static int divide(int n, int d) {
            if (d == 0)
                throw new IllegalArgumentException("Divisor is 0");
            return n / d;
        }
    
        public static void main(String[] args) {
            try {
                System.out.println("Performing division:");
                System.out.println( divide(5, 2) );
                System.out.println( divide(5, 0) );
                System.out.println( divide(5, 1) );
            } catch (IllegalArgumentException ex) {
                System.out.println("Caught exception");
            } finally {
                System.out.println("Done with division.");
            }
        }
    }
    
  4. Define a method that takes an array of Strings as input, and returns a Map<String, Integer> that stores the number of times that each unique string appears in the array.

  5. What does the following program print?

    class Printer {
        public void print(String x) {
            System.out.println(x);
        }
    }
    
    class Underliner extends Printer {
        @Override
        public void print(String x) {
            super.print(x);
            for (int i = 0; i < x.length(); i++)
                System.out.print("-");
            System.out.println();
        }
    }
    
    class Main {
        public static void main(String[] args) {
            Underliner u = new Underliner();
            u.print("Hello!");
        }
    }
    
  6. Working with the classes in #5, consider the following class below:

    class ModifiedPrinter extends Printer {
        Modifier mod;
        public ModifiedPrinter(Modifier m) {
            mod = m;
        }
    
        @Override
        public void print(String x) {
            super.print(mod.modify(x));
        }
    }
    

    How would you define the Modifier interface? Define a class Doubler that implements the interface so the ModifiedPrinter.print method prints its input in all upper case when a Doubler instance is passed to the ModifiedPrinter constructor.