Assignment 4: Using Interfaces for Templates and Function Objects

This is a short but tricky assignment that illustrates the basics of how interfaces are used in Java to implement generic algorithms (i.e. C++ templates) and function objects. It's a little hard to describe without giving away the solution, so I apologize if this requires several readings to make sense.

The C++ STL has a pair of functions called find and find_if. find searches a container for an item; find_if searches a container for an item that matches a particular predicate. You'll be writing something similar as three separate static methods.

Write a class that contains three static methods, as follows.

  1. Write a method that takes an array of Object and an Object x and returns a reference to the Object in the array that equals x (or null if there is no such object). The test is performed by calling the equals method. Test your method by writing a main that uses an array of Date.
  2. Write a second method that takes an array of Comparable and an Object x and returns a reference to the Comparable in the array that equals x (or null if there is no such object). This test is performed by calling the compareTo method that must be defined for Comparables.
    1. Test your method by using an array of Date. (You will need to modify Date.)
    2. Test your method by using an array of Employee, initialized with different subclasses (such as SalariedEmployee, HourlyEmployee). You should be able to pass any kind of concrete Employee and match any Employee derived object on the basis of social security number. For instance you can create a Salary object with SSN "123-45-6789" and have that match any Employee with SSN "123-45-6789". (Unfortunately, Employee is abstract, so we cannot create one of those, which would be more natural.) Again, you will need to make a change in Employee so that it is a Comparable.
  3. The third version of find takes an array of Object, an Object to search for, and a function predicate. The function predicate implements the interface Predicate. This interface supports one method:
    boolean equals( Object lhs, Object rhs );
    
    which returns true if lhs and rhs are to be considered equal. Test the predicate by using the array of Employees from the previous function. To be able to call the three-parameter find you will need to create a function object that will return true if two Employees are equal (the implementation will be based on the compareTo function). Note that Employee no longer needs to implement the Comparable interface, but there is no harm in doing so.
Finally, rewrite the first two versions of find so that they both call the third version. To do so, you'll need to write two classes that generically implement the function object. In other words, for the first case:
    public static Object find( Object [] a, Object x )
    {
          // Call the three-parameter find
        return find( a, x, new StandardEquals( ) );
    }
where StandardEquals is defined along the lines of
class StandardEquals ...
{
    public boolean equals ...
}
The easiest implementation of StandardEquals is to call the equals method for the two objects. Make sure you do not generate a NullPointerException!

You should submit your revised Date and Employee classes and the three static methods that you rewrote at the end (i.e. in the "finally paragraph"), and a test program with output that proves your program works and handles degenerate cases.