Ошибка несовместимого типа для того же типа при использовании компаратора - PullRequest
1 голос
/ 24 апреля 2020

У меня есть универсальный c класс с именем 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
        };
    }

}

Всякий раз, когда я использую этот Comparator для сортировки List<Interval<T>>, он работает.

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 - это не естественный порядок сортировки, а порядок, в котором несколько классов используют сортировку для собственных целей.

1 Ответ

1 голос
/ 24 апреля 2020

Это должно работать, если вы разделяете оператор на два отдельных оператора:

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<Interval<Integer>>. Вам может потребоваться Comparator<Interval<String>> или Comparator<Interval<LocalDate>>, что касается компиляции, , потому что он не смотрит на вызов .compare при выводе параметров типа для вызова getIntervalComparator.

Что происходит, когда компилятор не знает? Он использует тип, связанный с параметром типа, то есть Comparable<? super T>, поэтому он думает, что вам нужен Comparator<Interval<T>>, но T на самом деле не существует ...

Другой способ исправить это:

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