I have a generic class called Interval
package com.test;
//import statements
public class Interval<T extends Comparable<? super T>> {
private boolean isStartInclusive;
private T start;
private T end;
private boolean isEndInclusive;
//Constructors
//Getter and Setters
//ToString
//Hashcode and Equals
//A public static method that returns comparator for use by other classes
public static <T extends Comparable<? super T>> Comparator<Interval<T>> getIntervalComparator() {
return (o1, o2) -> {
//comparing logic that returns -1 or 1 or 0
};
}
}
Whenever I use this Comparator
to sort a List<Interval<T>>
it works.
List<Interval<T>> intervalsList1 = getIntervalsList();
intervalsList1.sort(Interval.getIntervalComparator());
But when I do this
List<Interval<T>> intervalsList1 = getIntervalsList1();
List<Interval<T>> intervalsList2 = getIntervalsList2();
Interval<T> interval1 = intervalsList1.get(i);
Interval<T> interval2 = intervalsList2.get(i);
int compareOneVsTwo = Interval.getIntervalComparator().compare(interval1, interval2); //line 85
I get an error saying
Error:(85, 76) java: incompatible types: com.test.Interval<T> cannot be converted to com.test.Interval<T>
Even when I do this
Interval<Integer> integerInterval1 = new Interval<>(true, 1, 2, true);
Interval<Integer> integerInterval2 = new Interval<>(true, 4, 5, true);
int compareOneVsTwo = Interval.getIntervalComparator().compare(integerInterval1, integerInterval2); //line 115
I get this error:
Error:(115, 72) java: incompatible types: com.test.Interval<java.lang.Integer> cannot be converted to com.test.Interval<T>
I do not understand what is causing this compilation error. The comparator inside the Interval
class is not the natural sort order, but the order in which multiple classes use when they sort for their own purpose.
It should work if you separate the statement into two separate statements:
Comparator<Interval<T>> compareOneVsTwo = Interval.getIntervalComparator();
compareOneVsTwo.compare(interval1, interval2);
// or in the integer case:
Comparator<Interval<Integer>> compareOneVsTwo = Interval.getIntervalComparator();
compareOneVsTwo.compare(interval1, interval2);
(assuming T
is an existing type)
This is because when they are the same statement, the compiler is not smart enough to know that you need a Comparator<Interval<Integer>>
. You could need a Comparator<Interval<String>>
or a Comparator<Interval<LocalDate>>
, as far as the compile is concerned, because it doesn't look at the .compare
call when inferring the type parameters for the getIntervalComparator
call.
What happens when the compiler doesn't know? It uses the type bound on the type parameter, ie Comparable<? super T>
Comparable<? super T>
, so it thinks you need a Comparator<Interval<T>>
, but T
doesn't actually exist...
Another way to fix this is:
Interval.<Integer>getIntervalComparator().compare(...)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.