【问题标题】:Incompatible Type error on same type when using Comparator使用比较器时相同类型的不兼容类型错误
【发布时间】:2020-08-07 20:45:21
【问题描述】:

我有一个名为 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
        };
    }

}

每当我使用此ComparatorList&lt;Interval&lt;T&gt;&gt; 进行排序时,它都会起作用。

List<Interval<T>> intervalsList1 = getIntervalsList();
intervalsList1.sort(Interval.getIntervalComparator());

但是当我这样做时

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

我收到一个错误提示

Error:(85, 76) java: incompatible types: com.test.Interval<T> cannot be converted to com.test.Interval<T>

即使我这样做

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

我收到此错误:

Error:(115, 72) java: incompatible types: com.test.Interval<java.lang.Integer> cannot be converted to com.test.Interval<T>

我不明白是什么导致了这个编译错误。 Interval 类中的比较器不是自然的排序顺序,而是多个类在为自己的目的进行排序时使用的顺序。

【问题讨论】:

    标签: java generics comparator


    【解决方案1】:

    如果将语句分成两个单独的语句,它应该可以工作:

    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);
    

    (假设T 是现有类型)

    这是因为当它们是相同的语句时,编译器不够聪明,无法知道您需要Comparator&lt;Interval&lt;Integer&gt;&gt;。就编译而言,您可能需要Comparator&lt;Interval&lt;String&gt;&gt;Comparator&lt;Interval&lt;LocalDate&gt;&gt;因为在推断getIntervalComparator 调用的类型参数时,它不会查看.compare 调用。强>

    当编译器不知道时会发生什么?它使用类型参数上绑定的类型,即Comparable&lt;? super T&gt;,所以它认为你需要一个Comparator&lt;Interval&lt;T&gt;&gt;,但T实际上并不存在...

    解决此问题的另一种方法是:

    Interval.<Integer>getIntervalComparator().compare(...)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-23
      • 1970-01-01
      • 1970-01-01
      • 2013-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多