遇到了泛型链式比较器的错误。

huangapple go评论192阅读模式
英文:

Geting Error For Generic Chained Comparator

问题

在提出这个问题之前,我想说我对Java泛型还不熟悉。我尝试实现了一个用于类的比较器链的类,因此我创建了以下类。

  1. static class ChainComparator implements Comparator<StudentDTO> {
  2. List<Comparator<StudentDTO>> chainComparators;
  3. @SafeVarargs
  4. public ChainComparator(Comparator<StudentDTO>... comparators) {
  5. chainComparators = Arrays.asList(comparators);
  6. }
  7. @Override
  8. public int compare(StudentDTO o1, StudentDTO o2) {
  9. for (Comparator<StudentDTO> comparator : chainComparators) {
  10. int result = comparator.compare(o1, o2);
  11. if (result != 0) {
  12. return result;
  13. }
  14. }
  15. return 0;
  16. }
  17. }

我创建了这个类以实现Student类的多个比较器。现在我认为这可以用于所有类,所以我尝试了以下类。

  1. public class ChainComparator implements Comparator<Class<?>>{
  2. List<Comparator<?>> chainComparators;
  3. @SafeVarargs
  4. public ChainComparator(Comparator<?>... comparators) {
  5. chainComparators = Arrays.asList(comparators);
  6. }
  7. @Override
  8. public int compare(Class<?> o1, Class<?> o2) {
  9. for (Comparator<?> comparator : chainComparators) {
  10. int result = comparator.compare(o1, o2);
  11. if (result != 0) {
  12. return result;
  13. }
  14. }
  15. return 0;
  16. }
  17. }

但是在这里,我得到了以下编译错误。

  1. 类型 Comparator<capture#1-of ?> 中的方法 compare(capture#1-of ?, capture#1-of ?) 对于参数 (Class<capture#2-of ?>, Class<capture#3-of ?>) 不适用

我在以下行上得到了上述错误。

  1. 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.

  1. static class ChainComparator implements Comparator&lt;StudentDTO&gt; {
  2. List&lt;Comparator&lt;StudentDTO&gt;&gt; chainComparators;
  3. @SafeVarargs
  4. public ChainComparator(Comparator&lt;StudentDTO&gt;... comparators) {
  5. chainComparators = Arrays.asList(comparators);
  6. }
  7. @Override
  8. public int compare(StudentDTO o1, StudentDTO o2) {
  9. for (Comparator&lt;StudentDTO&gt; comparator : chainComparators) {
  10. int result = comparator.compare(o1, o2);
  11. if (result != 0) {
  12. return result;
  13. }
  14. }
  15. return 0;
  16. }
  17. }

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.

  1. public class ChainComparator implements Comparator&lt;Class&lt;?&gt;&gt;{
  2. List&lt;Comparator&lt;?&gt;&gt; chainComparators;
  3. @SafeVarargs
  4. public ChainComparator(Comparator&lt;?&gt;... comparators) {
  5. chainComparators = Arrays.asList(comparators);
  6. }
  7. @Override
  8. public int compare(Class&lt;?&gt; o1, Class&lt;?&gt; o2) {
  9. for (Comparator&lt;?&gt; comparator : chainComparators) {
  10. int result = comparator.compare(o1, o2);
  11. if (result != 0) {
  12. return result;
  13. }
  14. }
  15. return 0;
  16. }
  17. }

But here I am getting the following compilation error

  1. The method compare(capture#1-of ?, capture#1-of ?) in the type Comparator&lt;capture#1-of ?&gt; is not applicable for the arguments (Class&lt;capture#2-of ?&gt;, Class&lt;capture#3-of ?&gt;)

I am getting this above error on the below line

  1. 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),其中 ABC 都可以是任何东西(通配符),但你不能将 Class<B>Class<C> 进行比较。

你需要声明一个泛型参数。

  1. static class ChainComparator<T> implements Comparator<T> {
  2. List<Comparator<T>> chainComparators;
  3. @SafeVarargs
  4. public ChainComparator(Comparator<T>... comparators) {
  5. chainComparators = Arrays.asList(comparators);
  6. }
  7. @Override
  8. public int compare(T o1, T o2) {
  9. for (Comparator<T> comparator : chainComparators) {
  10. int result = comparator.compare(o1, o2);
  11. if (result != 0) {
  12. return result;
  13. }
  14. }
  15. return 0;
  16. }
  17. }

然后,你可以使用 diamond 运算符来使用它:

  1. Comparator<Foo> chain = new ChainComparator<>(fooComparator1, fooComparator2);
英文:

You can't use wildcards here, because every wildcard is independent of the others.

Comparator&lt;?&gt; and compare(Class&lt;?&gt; o1, Class&lt;?&gt; o2) can be considered as meaning Comparator&lt;A&gt; and compare(Class&lt;B&gt; o1, Class&lt;C&gt; o2), where A, B, and C can each be anything (wildcard), but you cannot of cause compare a Class&lt;B&gt; with a Class&lt;C&gt;.

What you need to do is declare a generic parameter.

  1. static class ChainComparator&lt;T&gt; implements Comparator&lt;T&gt; {
  2. List&lt;Comparator&lt;T&gt;&gt; chainComparators;
  3. @SafeVarargs
  4. public ChainComparator(Comparator&lt;T&gt;... comparators) {
  5. chainComparators = Arrays.asList(comparators);
  6. }
  7. @Override
  8. public int compare(T o1, T o2) {
  9. for (Comparator&lt;T&gt; comparator : chainComparators) {
  10. int result = comparator.compare(o1, o2);
  11. if (result != 0) {
  12. return result;
  13. }
  14. }
  15. return 0;
  16. }
  17. }

You would then use it using the diamond operator:

  1. Comparator&lt;Foo&gt; chain = new ChainComparator&lt;&gt;(fooComparator1, fooComparator2);

huangapple
  • 本文由 发表于 2020年7月26日 01:34:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/63091440.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定