此作业是我的Java类的泛型部分的一部分。我认为我通过使其过于笼统而将问题缠绕在一般性上。对于这个特定的类,我必须为我给出的任何泛型Collection实现min(和其他几个)方法,并使用给定的比较器(comp)来评估它们。
已实施的代码:
public static <T> T min(Collection<T> c, Comparator<T> comp)
throws IllegalArgumentException, NoSuchElementException {
if (c != null && comp != null) {
if (!c.isEmpty()) {
T min = (T) null;
for (T t : c) {
if (min == null) {
min = t;
} else if (comp.compare(t, min) < 0) {
min = t;
}
}
return min;
} else {
throw new NoSuchElementException();
}
} else {
throw new IllegalArgumentException();
}
}
我的问题是我不知道如何用我的一个比较器测试这个方法。我会解释我读过的东西/我如何理解它,如果你们能告诉我在哪里错过了什么,那就太棒了。
如果我想在一个类中进行比较(添加我自己的compare / compareTo方法):
public class Example<T extends Comparator<T>> {
}
如果我想将自己独立的类编写为比较器:
public class ExampleComp<T> implements Comparator<T> {
@override
public int compare(T o1, T o2) {
//do fancy things here
}
}
这意味着我应该编写测试用例的方法是实现我自己的比较器类,并在我的方法调用中将new ExampleComp()
作为变量传递。
因此,如果我对此的理解是正确的,那么如何编写测试用例来比较任何事物和所有内容?集合应该尽可能通用,那么如何在保持一切类型安全的同时实现比较一块到另一块的方法呢?
答案 0 :(得分:1)
目前,您的所有类型都是不变的。 Collection<T>
是一个组件类型为T的集合。List<T>
将匹配此类型,但Collection不会。还有两个使用通配符的可能组件定义,它们是协变(<? extends T>
)和逆变(<? super T>
)组件类型。
在您的情况下,我们可以使Collection协变,但这意味着您的结果类型将取决于Comparator类型。因此,优选的解决方案是使比较器逆变。然后你的方法变成:
public static <T> T min(Collection<T> c, Comparator<? super T> comp)
throws IllegalArgumentException, NoSuchElementException {…}
这是有效的,因为我们的comp将采用任何比较至少超出T的超类型的比较器。所以如果你有一个class Person
和一个子类VeryIncompetentPerson
,Comparator<Person>
就足够了从一群非常无能的人中获得最低限度。