13

次のエラーメッセージが表示されます。

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 method compareTo(capture#1-of ?) in the type Comparable<capture#1-of ?> is not applicable for the arguments (Comparable<capture#2-of ?>)

何が起きてる?このリストComparableを呼び出して並べ替えることができるように、すべてのタイプを作成しました。.compareToジェネリックを誤って使用していますか?

4

1 に答える 1

21

List<?>は「何かのリスト」を意味するため、このタイプの 2 つのオブジェクトは同じではありません。1 つは のリストでありString、もう 1 つは のリストですBigDecimal。明らかに、それらは同じではありません。

List<T>Tは、「すべてのリストですが、もう一度見ると同じですT」という意味です。

異なる場所で同じ型を意味する場合は、コンパイラに通知する必要があります。試す:

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();

[編集] では、どういう<T extends Comparable<? super T>> List<T>意味ですか? 最初の部分はT、次のプロパティを持つ型を定義します: インターフェイスを実装する必要がありますComparable<? super T>(またはComparable<X>whereXも に関して定義されますT)。

? super TComparableがサポートしなければならない型、Tまたはそのスーパー型の 1 つであることを意味します。

この継承を少し想像してみてください: Double extends Integer extends Number. これは Java では正しくありませんが、プラスの小数部分にDoubleすぎないと想像してください。Integerこのシナリオでは、Comparableで機能する a は、 で機能し、両方とも から派生するNumberため、 で機能します。そのため、、またはの部分を満たします。IntegerDoubleNumberComparable<Number>superTNumberIntegerDouble

これらの各型がComparableインターフェイスをサポートしている限り、宣言の最初の部分も満たします。Numberつまり、 forを渡すことができT、結果のコードは、リストにIntegerおよびDoubleインスタンスがある場合にも機能します。の場合はIntegerT引き続き使用できますが、DoubleもはやNumber満足できないため、使用できT extends Comparableません (ただし、superパーツはまだ機能します)。

static次のステップは、との間の式が、コードの後半で使用されるList型のプロパティを宣言しているだけであることを理解することです。Tこのように、この長い宣言を何度も繰り返す必要はありません。これはメソッドの動作の一部 ( などpublic) であり、実際のコードの一部ではありません。

于 2009-11-20T15:13:39.830 に答える