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

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

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&lt;StudentDTO&gt; {
	
	List&lt;Comparator&lt;StudentDTO&gt;&gt; chainComparators;

	@SafeVarargs
	public ChainComparator(Comparator&lt;StudentDTO&gt;... comparators) {
		chainComparators = Arrays.asList(comparators);
	}

	@Override
	public int compare(StudentDTO o1, StudentDTO o2) {
		for (Comparator&lt;StudentDTO&gt; 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&lt;Class&lt;?&gt;&gt;{
	List&lt;Comparator&lt;?&gt;&gt; chainComparators;

	@SafeVarargs
	public ChainComparator(Comparator&lt;?&gt;... comparators) {
		chainComparators = Arrays.asList(comparators);
	}
	@Override
	public int compare(Class&lt;?&gt; o1, Class&lt;?&gt; o2) {
		for (Comparator&lt;?&gt; 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&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

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> 进行比较。

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

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

static class ChainComparator&lt;T&gt; implements Comparator&lt;T&gt; {
    
    List&lt;Comparator&lt;T&gt;&gt; chainComparators;

    @SafeVarargs
    public ChainComparator(Comparator&lt;T&gt;... comparators) {
        chainComparators = Arrays.asList(comparators);
    }

    @Override
    public int compare(T o1, T o2) {
        for (Comparator&lt;T&gt; 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&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:

确定