Reminder <T> is needed when the type is Generic. <T> T because Java might think T is some class name.


max3(-1, 2, -3, (x, y) x - y)) Comparator is an interfartttce that defines its single abstract method is called compare, something like:

public interface Comparator<T> {
    int compare(T o1, T o2);
}

So Java knows this lambda expression is the implementation of compare for the Comparator object comp.

How it works -1 is set as the maximum. com.compare(T a, T b) basically returns a - b. If this is positive, then a is bigger than b. Set max to be a.

If you want to use Object instead of Integer The implementation is different. Java infers T = Integer from the three integers. Does Comparator<Object> satisfy Comparator<? super Integer>? Yes because, Object is a super class of Integer.

? super Integer says “I’ll accept any Comparator<X> where X is an Integer or a superclass of Integer”.


There is no guarantee that an object of type T implements the Comparable<T> interface. Most custom classes you write won’t have it unless you explicitly add it.

class Dog {
    String name;
}

Dog has no compareTo method. It doesn't implement Comparable<Dog>. 

Method 1: Okay, let’s make sure all the arguments are of Comparable type

Integer implements Comparable<Integer>, but Comparable<Integer> is not the same type as Integer. So when you write T max = a, you’re trying to assign a Comparable<T> to a T — type mismatch.


Method 2: Let’s make sure ALL objects are of a type that extends Comparable<T>

Imagine

class Animal implements Comparable<Animal> { ... }
class Dog extends Animal { }

Dog doesn’t implement Comparable<Dog>, so Dog extends Comparable<Dog> wouldn’t make sense but Dog extends Comparable<Animal> makes sense, hence we need <T extends Comparable<? super T>>


The problem: Comparable<Orange> does not exist.

Method 1: Relax parameter List<? extends T> Java tries T = Orange first This doesn’t work because Orange doesn’t implement Comparable<Orange>. Java walks up the hierarchy: what about T = Fruit?

  1. Does List<Orange> fit List<? extends Fruit>? Yes.
  2. Does Fruit extends Comparable<Fruit>? Yes. Both constraints satisfied — Java picks T = Fruit.

Downside: Orange o = maxList(oranges) fail. You get a Fruit back.

Method 2: Relax bound Comparable<? super T> instead of Comparable<T> The check is “does Orange implement Comparable<something that is Orange or above>?” Yes. That is Comparable<Fruit>, and Fruit is a superclass of Orange. Return type is Orange. So Orange o = maxList(oranges) works. Technically, this covers both 1 and 2.

<T extends Comparable<? super T>> T maxList(List<? extends T> list)