英文:
Geting Error For Generic Chained Comparator
问题
在提出这个问题之前,我想说我对Java泛型还不熟悉。我尝试实现了一个用于类的比较器链的类,因此我创建了以下类。
static class ChainComparator implements Comparator<StudentDTO> {
List<Comparator<StudentDTO>> chainComparators;
@SafeVarargs
public ChainComparator(Comparator<StudentDTO>... comparators) {
chainComparators = Arrays.asList(comparators);
}
@Override
public int compare(StudentDTO o1, StudentDTO o2) {
for (Comparator<StudentDTO> comparator : chainComparators) {
int result = comparator.compare(o1, o2);
if (result != 0) {
return result;
}
}
return 0;
}
}
我创建了这个类以实现Student类的多个比较器。现在我认为这可以用于所有类,所以我尝试了以下类。
public class ChainComparator implements Comparator<Class<?>>{
List<Comparator<?>> chainComparators;
@SafeVarargs
public ChainComparator(Comparator<?>... comparators) {
chainComparators = Arrays.asList(comparators);
}
@Override
public int compare(Class<?> o1, Class<?> o2) {
for (Comparator<?> comparator : chainComparators) {
int result = comparator.compare(o1, o2);
if (result != 0) {
return result;
}
}
return 0;
}
}
但是在这里,我得到了以下编译错误。
类型 Comparator<capture#1-of ?> 中的方法 compare(capture#1-of ?, capture#1-of ?) 对于参数 (Class<capture#2-of ?>, Class<capture#3-of ?>) 不适用
我在以下行上得到了上述错误。
comparator.compare(o1, o2);
有人能帮助我理解为什么会出现这个错误,以及我如何解决这个错误,或者我的方法本身是否有问题。
我可以理解,如果我使用其他库或Java 8,我可以通过一些不错的代码来很快实现这一点,但实际上我只是好奇,想更多地学习和理解泛型。
英文:
Before asking this question I want to say I am new in Java Generics. I have tried to implement Comparator chaining for a class so I have created this following class.
static class ChainComparator implements Comparator<StudentDTO> {
List<Comparator<StudentDTO>> chainComparators;
@SafeVarargs
public ChainComparator(Comparator<StudentDTO>... comparators) {
chainComparators = Arrays.asList(comparators);
}
@Override
public int compare(StudentDTO o1, StudentDTO o2) {
for (Comparator<StudentDTO> comparator : chainComparators) {
int result = comparator.compare(o1, o2);
if (result != 0) {
return result;
}
}
return 0;
}
}
Here this class I have created for multiple comparator implementation for Student class. Now I am thinking this can be generic for all classes so I have tried with the following class.
public class ChainComparator implements Comparator<Class<?>>{
List<Comparator<?>> chainComparators;
@SafeVarargs
public ChainComparator(Comparator<?>... comparators) {
chainComparators = Arrays.asList(comparators);
}
@Override
public int compare(Class<?> o1, Class<?> o2) {
for (Comparator<?> comparator : chainComparators) {
int result = comparator.compare(o1, o2);
if (result != 0) {
return result;
}
}
return 0;
}
}
But here I am getting the following compilation error
The method compare(capture#1-of ?, capture#1-of ?) in the type Comparator<capture#1-of ?> is not applicable for the arguments (Class<capture#2-of ?>, Class<capture#3-of ?>)
I am getting this above error on the below line
comparator.compare(o1, o2);
Can anyone please help me to understand why I am getting this error and how I can solve this error or my approach itself is wrong.
I can understand if I use any other library or Java8 I can achieve this very quickly with a decent code but actually I just curious and wanted to learn and understand Generic more.
答案1
得分: 1
这里不能使用通配符,因为每个通配符都是独立的。
Comparator<?>
和 compare(Class<?> o1, Class<?> o2)
可以被视为表示 Comparator<A>
和 compare(Class<B> o1, Class<C> o2)
,其中 A
、B
和 C
都可以是任何东西(通配符),但你不能将 Class<B>
与 Class<C>
进行比较。
你需要声明一个泛型参数。
static class ChainComparator<T> implements Comparator<T> {
List<Comparator<T>> chainComparators;
@SafeVarargs
public ChainComparator(Comparator<T>... comparators) {
chainComparators = Arrays.asList(comparators);
}
@Override
public int compare(T o1, T o2) {
for (Comparator<T> comparator : chainComparators) {
int result = comparator.compare(o1, o2);
if (result != 0) {
return result;
}
}
return 0;
}
}
然后,你可以使用 diamond 运算符来使用它:
Comparator<Foo> chain = new ChainComparator<>(fooComparator1, fooComparator2);
英文:
You can't use wildcards here, because every wildcard is independent of the others.
Comparator<?>
and compare(Class<?> o1, Class<?> o2)
can be considered as meaning Comparator<A>
and compare(Class<B> o1, Class<C> o2)
, where A
, B
, and C
can each be anything (wildcard), but you cannot of cause compare a Class<B>
with a Class<C>
.
What you need to do is declare a generic parameter.
static class ChainComparator<T> implements Comparator<T> {
List<Comparator<T>> chainComparators;
@SafeVarargs
public ChainComparator(Comparator<T>... comparators) {
chainComparators = Arrays.asList(comparators);
}
@Override
public int compare(T o1, T o2) {
for (Comparator<T> comparator : chainComparators) {
int result = comparator.compare(o1, o2);
if (result != 0) {
return result;
}
}
return 0;
}
}
You would then use it using the diamond operator:
Comparator<Foo> chain = new ChainComparator<>(fooComparator1, fooComparator2);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论