masiboo
masiboo

Reputation: 4719

How does this Java sorting work?

The following code is working fine. But I can't understand how it works? Could you please explain? Especially the method signature of sortEmployeeByCriteria (see below).

I understood it returns List<T> but what is <T, U extends Comparable<? super U>>?

public static void sortIt() {
    Employee[] employees = new Employee[] {
        new Employee("John", 25, 3000.0, 9922001),
        new Employee("Ace", 22, 20000.0, 5924001),
        new Employee("Keith", 35, 4000.0, 3924401)
    };

    List<Employee> employeeList  = Arrays.asList(employees);
    List<Employee> list = sortEmployeeByCriteria(employeeList, Employee::getName);
    list.stream().forEach(System.out::println);
}

// But could you please explain the method signature how is it working
public static <T, U extends Comparable<? super U>> List<T> sortEmployeeByCriteria( List<T> list, Function<? super T, ? extends U> byCriteria) {
    Comparator<? super T> comparator = Comparator.comparing(byCriteria);
    list.sort(comparator);
    return list;
}

Upvotes: 3

Views: 109

Answers (2)

syntagma
syntagma

Reputation: 24324

The answer lies in the first line of the sortEmployeeByCriteria():

Comparator<? super T> comparator = Comparator.comparing(byCriteria);

Looking at the documentation of Comparator.comparing() (a static method, same as sortEmployeeByCriteria()):

static <T,U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T,? extends U> keyExtractor)

Accepts a function that extracts a Comparable sort key from a type T, and returns a Comparator that compares by that sort key.

So the <T, U extends Comparable<? super U>> is a type parameter in a static method (static <T> void someMethod(U objectOfTypeU)), which has some bounds required by the Comparator.comparing() method. It also allows you to use (generic) type T as a return value (i.e. List<T>).

Upvotes: 3

Luke
Luke

Reputation: 1344

It's not a lambda - it's a method reference (the Employee::getName part). sortEmployeeByCriteria is just an ordinary generic static method, taking a List of type T, and a Function which takes a T (or subclass) and produces something of type U (or subclass) and returns a (sorted) List of type T.

The unusual part is probably Comparator#comparing, which creates a Comparator which will compare Ts by the given mapping, i.e. it transforms T, in your case an Employee, to U, in your case a String (result of getName), which it knows how to compare because String implements Comparable. It then proceeds to actually sort them using List#sort(Comparator).

Employee::getName is basically a shorthand, a method reference you can pass instead of creating your own Function instance.

Upvotes: 1

Related Questions