Java 泛型:compareTo 和“capture#1-of ?”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1770972/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 17:54:38  来源:igfitidea点击:

Java Generics: compareTo and "capture#1-of ?"

javagenericscomparable

提问by Nick Heiner

The following gives me an error message:

以下给了我一条错误消息:

public static List<Comparable<?>> merge(Set<List<Comparable<?>>> lists) {
    List<Comparable<?>> result = new LinkedList<Comparable<?>>();
    HashBiMap<List<Comparable<?>>, Integer> location = HashBiMap.create();

    int totalSize;
    for (List<Comparable<?>> l : lists) {
        location.put(l, 0);
        totalSize += l.size();
    }

    boolean first;
    List<Comparable<?>> lowest; //the list with the lowest item to add
    int index;

    while (result.size() < totalSize) {
        first = true;

        for (List<Comparable<?>> l : lists) {
            if (! l.isEmpty()) {
                if (first) {
                    lowest = l;
                }
                else if (l.get(location.get(l)).compareTo(lowest.get(location.get(lowest))) <= 0) { //error here
                    lowest = l;
                }
            }
        }
        index = location.get(lowest);
        result.add(lowest.get(index));
        lowest.remove(index);
    }
    return result;
}

The error is:

错误是:

The method compareTo(capture#1-of ?) in the type Comparable<capture#1-of ?> is not applicable for the arguments (Comparable<capture#2-of ?>)

What's going on here? I made the type of everything Comparableso I could call .compareToand sort this list. Am I using generics incorrectly?

这里发生了什么?我制作了所有东西的类型,Comparable所以我可以调用.compareTo这个列表并对其进行排序。我是否错误地使用了泛型?

回答by Aaron Digulla

List<?>means "List of anything", so two objects with this type are not the same: One could be a list of String, the other a list of BigDecimal. Obviously, those are not the same.

List<?>手段“的任何名单”,所以这种类型的两个对象是不一样的:一个可能是一个列表String,另一名单BigDecimal。显然,这些并不相同。

List<T>means "List of anything but when you see Tagain, it's the same T".

List<T>意思是“任何东西的列表,但当你T再次看到时,它是一样的T”。

You must tell the compiler when you mean the same type in different places. Try:

当您在不同地方表示相同类型时,您必须告诉编译器。尝试:

public static <T extends Comparable<? super T>> List<T> merge(Set<List<T>> lists) {
    List<T> result = new LinkedList<T>();
    HashBiMap<List<T>, Integer> location = HashBiMap.create();

[EDIT] So what does <T extends Comparable<? super T>> List<T>mean? The first part defines a type Twith the following properties: It must implement the interface Comparable<? super T>(or Comparable<X>where Xis also defined in terms of T).

[编辑] 那是什么<T extends Comparable<? super T>> List<T>意思?第一部分定义了一个T具有以下属性的类型: 它必须实现接口Comparable<? super T>(或Comparable<X>whereX也用 定义T)。

? super Tmeans that the type which the Comparablesupports must Tor one of its super types.

? super T表示Comparable必须支持的类型T或其超类型之一。

Imagine for a moment this inheritance: Double extends Integer extends Number. This is not correct in Java but imagine that Doubleis just an Integerplus a fraction part. In this scenario, a Comparablewhich works for Numberalso works for Integerand Doublesince both derive from Number. So Comparable<Number>would satisfy the superpart for Tbeing Number, Integeror Double.

想象一下这个继承:Double extends Integer extends Number. 这在 Java 中是不正确的,但想象一下这Double只是一个Integer加分部分。在这种情况下,Comparable适用于的 aNumber也适用于Integer并且Double因为两者都来自Number. 所以Comparable<Number>会满足存在,或的super部分。TNumberIntegerDouble

As long as each of these types support the Comparableinterface, they also satisfy the first part of the declaration. This means, you can pass in Numberfor Tand the resulting code will also work when there are Integerand Doubleinstances in the lists. If you Integerfor T, you can still use Doublebut Numberis not possible because it doesn't satisfy T extends Comparableanymore (the superpart would still work, though).

只要这些类型中的每一种都支持Comparable接口,它们也满足声明的第一部分。这意味着,您可以传入NumberforT并且当列表中有IntegerDouble实例时,生成的代码也将起作用。如果您IntegerT,您仍然可以使用DoubleNumber不可能,因为它不再满足T extends Comparablesuper尽管该部分仍然可以工作)。

The next step is to understand that the expression between staticand Listjust declares the properties of the type Twhich is used later in the code. This way, you don't have to repeat this long declaration over and over again. It's part of the behavior of the method (like public) and not part of the actual code.

下一步是理解static和之间的表达式List只是声明了T稍后在代码中使用的类型的属性。这样,您就不必一遍又一遍地重复这个冗长的声明。它是方法行为的一部分(如public),而不是实际代码的一部分。