泛型、比较器和测试用例

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> 将足以从一群非常无能的人中获得最低限度。