Solution: Max by a Comparator

The natural-order max can only use one order, the one compareTo defines. To find the largest element by some other order, overload max to take a Comparator, the same way the chapter overloaded selectionSort.

Solution

The loop is the same. Only the comparison changes. Instead of calling compareTo on the element, we pass both elements to the comparator’s compare.

public static <T> T max(DynamicArray<T> a, Comparator<T> cmp) {
  T best = a.get(0);
  for (int i = 1; i < a.size(); i++) {
    if (cmp.compare(a.get(i), best) > 0) {
      best = a.get(i);
    }
  }
  return best;
}

There is no <T extends Comparable<T>> here, and there is no reason to add one. T does not need to know how to compare itself, because cmp supplies the order. So max now works on any type, comparable or not, as long as the caller supplies a Comparator for that type.

If we pass it the SuitComparator from the Card problem, it can return a different card than the natural-order max returns on the same hand. The natural order ranks by rank first, so it returns the highest card. SuitComparator ranks by suit first, so it returns the highest card of the highest suit, and that card may be a lower rank. Both answers are correct. They use different orders.