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