泛型、比较器和测试用例
Generics, Comparators, and Test Cases
此作业是我的 Java class 泛型部分的一部分。我认为我在将通用性变得过于通用时遇到了一些问题。对于这个特定的 class,我必须为我提供的任何通用 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();
}
}
我的问题是我不知道如何用我的一个比较器测试这个方法。我会解释我所知道的 read/how 我明白了,如果你们能告诉我我遗漏了什么,那就太好了。
如果我想在 class 中进行比较(添加我自己的 compare/compareTo 方法):
public class Example<T extends Comparator<T>> {
}
如果我想单独写一个class作为比较器:
public class ExampleComp<T> implements Comparator<T> {
@override
public int compare(T o1, T o2) {
//do fancy things here
}
}
这意味着我应该编写测试用例的方式是实现我自己的比较器 class 并在我的方法调用中将 new ExampleComp()
作为变量传递。
所以如果我的理解是正确的,我该如何编写测试用例来比较任何东西?集合应该尽可能通用,那么我如何实现方法来将一件与另一件进行比较,同时保持所有内容的类型安全?
目前,您的所有类型都是不变的。 Collection<T>
是一个组件类型为 T 的集合。List<T>
将匹配此类型,但 Collection 不会。使用通配符还有另外两种可能的组件定义,它们是 covariant (<? extends T>
) 和 contravariant (<? 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>
将足以从一群非常无能的人中获得最低限度。
此作业是我的 Java class 泛型部分的一部分。我认为我在将通用性变得过于通用时遇到了一些问题。对于这个特定的 class,我必须为我提供的任何通用 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();
}
}
我的问题是我不知道如何用我的一个比较器测试这个方法。我会解释我所知道的 read/how 我明白了,如果你们能告诉我我遗漏了什么,那就太好了。
如果我想在 class 中进行比较(添加我自己的 compare/compareTo 方法):
public class Example<T extends Comparator<T>> {
}
如果我想单独写一个class作为比较器:
public class ExampleComp<T> implements Comparator<T> {
@override
public int compare(T o1, T o2) {
//do fancy things here
}
}
这意味着我应该编写测试用例的方式是实现我自己的比较器 class 并在我的方法调用中将 new ExampleComp()
作为变量传递。
所以如果我的理解是正确的,我该如何编写测试用例来比较任何东西?集合应该尽可能通用,那么我如何实现方法来将一件与另一件进行比较,同时保持所有内容的类型安全?
目前,您的所有类型都是不变的。 Collection<T>
是一个组件类型为 T 的集合。List<T>
将匹配此类型,但 Collection 不会。使用通配符还有另外两种可能的组件定义,它们是 covariant (<? extends T>
) 和 contravariant (<? 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>
将足以从一群非常无能的人中获得最低限度。