The goal of this assignment is to perform searching operations (min, max, kmin, kmax) from a generic collection using a Comparator. The collection and Comparator are passed into the methods as c, and comp.

A common question is where do we get the c and comp. The answer is the user (client) of your class will supply both parameters and your responsibility is to make sure your class return correct values based on the parameters. In other words, when Web-Cat checks your code, it will pass in both c and comp.

Although c and comp will be passed in for you, as you write your code, you also need to check the correctness of your code; therefore, when you test your code, you become the user of your class and you have to write your own Comparators to use in test cases.

This note shows how to use and write Comparators for this assignment.

Using Comparator

The parameter comp is an instance of a Comparator class. As noted previously, the Comparator determines which element is greater than or less than the other.

The writer of the Comparator class decide the meaning of “greater than” and “less than”. This means that if they want, the writer of Comparator can make a smaller number “greater than” a number that is bigger.

The following example finds the minimum using a Comparator.

public class Selector {
    public static <T> T min(Collection<T> c, Comparator<T> comp) {
        T min = null;
        for(T e : c)
            if(min == null || comp.compare(e, min) < 0)
                min = e;
        return min;
    }
}

Writing Comparators

To test your code, you should write your own Comparators. For each way of comparing a collection, you should write a Comparator class. Here we’re going to write two integer Comparators, one ascending one descending, and one Comparator for the Data class below, which has 2 fields. For each please create a new .java file, with the same name as your class.

The following code shows an integer ascending Comparator (AscIntComparator.java).

import java.util.Comparator;
public class AscIntComparator implements Comparator<Integer> {
    public int compare(Integer a, Integer b) {
        return a.compareTo(b);
    }
}

The following code shows an integer ascending Comparator (DescIntComparator.java).

import java.util.Comparator;
public class DescIntComparator implements Comparator<Integer> {
    public int compare(Integer a, Integer b) {
        return b.compareTo(a);
    }
}

Note that the only difference between the two classes is the reversal of the return values. In other words, if we sort using the DescIntComparator class, we would get a reversely sorted array.

The following shows the Data class and corresponding Comparator.

public class Data {
    public String s;
    public int    i;

    public Data(String s, int i) {
        this.s = s;
        this.i = i;
    }
}
import java.util.Comparator;
public class DataStrAscComparator implements Comparator<Data> {
    public int compare(Data a, Data b) {
        return a.s.compareTo(b.s);
    }
}

Writing jUnit Test Cases

The following is an example test case for the min method.

import org.junit.*;
import static org.junit.Assert.*;
import java.util.*;

public class SelectorTest {
    private AscIntComparator ascComp;
    private DescIntComparator desComp;
    private DataStrAscComparator dataAscComp;
    
    /** Fixture initialization (common initialization for all tests). **/
    @Before public void setUp() {
        ascComp = new AscIntComparator();
        desComp = new DescIntComparator();
        dataAscComp = new DataStrAscComparator();
    }

    @Test public void testMinAsc() {
        List<Integer> list = Arrays.asList(2, 1, 3, 4);
        int expected = 1;
        int actual   = Selector.min(list, ascComp);
        Assert.assertEquals(expected, actual);
    }

    @Test public void testMinDesc() {
        List<Integer> list = Arrays.asList(2, 1, 3, 4);
        int expected = 4;
        int actual   = Selector.min(list, desComp);
        Assert.assertEquals(expected, actual);
    }

    @Test public void testDataStrAsc() {
        List<Data> list = Arrays.asList(new Data("A",5), new Data("B",4), new Data("C",3));
        Data result = Selector.min(list, dataAscComp);
        Assert.assertEquals(list.get(0).s, result.s);
        Assert.assertEquals(list.get(0).i, result.i);
    }
}