I have a list of class that I want to sort:
class Student {
private Integer studentId;
private Double scoreA;
private Integer scoreB;
private Long scoreC;
// ... getter/setter...
}
And I want to make a helper class (with static methods) that can be used to sort the Student list:
public class SortHelper {
public static <T> void Sort(List<T> list, Function<T, Double> fn) { // Double
Collections.sort(list, Comparator.comparing(fn));
}
}
However, the above method only takes Double - but I'd like to pass all Number object to the method:
public static <T> void Sort(List<T> list, Function<T, Number> fn) { // `Number`
Collections.sort(list, Comparator.comparing(fn)); // Error!
}
// so that I can do:
List<Student> students = loadStudents();
SortHelper.Sort(students, Student::getScoreA); // Double
SortHelper.Sort(students, Student::getScoreB); // Integer
SortHelper.Sort(students, Student::getScoreC); // Long
When I use Number instead of Double, it gives an error The method comparing(Function<? super T,? extends U>) in the type Comparator is not applicable for the arguments (Function<T,Number>)
My questions are:
Number instead of Double not possible?SortHelper to use Number instead of Double?Please help me out..!
I believe you're facing this issue because Comparator#comparing expects a Function<T, U> whose output U extends Comparable<? super U>.
Number does not implement Comparable<? super Number>.
One solution is to specify a new generic type that extends Number and also extends Comparable:
public static <T, U extends Number & Comparable<? super U>> void Sort(List<T> list, Function<T, U> fn) {
Collections.sort(list, Comparator.comparing(fn));
}
Or equivalently, you can use List#sort:
public static <T, U extends Number & Comparable<? super U>> void Sort(List<T> list, Function<T, U> fn) {
list.sort(Comparator.comparing(fn));
}
This is what's known as an intersection type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With