2010-08-10 3 views
4

이것은 호환 가능한 키가있는 다른 컨테이너와 비교할 수있는 컨테이너의 구현입니다. Java에서 제네릭을 사용하는 이상한 오류가 있습니까? 당신은 단순히 올바르게 인터페이스를 구현하지 않는Java 일반 캡쳐 및 비교 가능

compareTo(capture#98 of ? super Key) in 
    java.lang.Comparable<capture#98 of ? super Key> cannot be applied to 
    (java.lang.Comparable<? super capture#822 of ? super Key>) 
      return key.compareTo(o.key); 
        ^
    1 error 
+0

좋아, 내가 그것을 이해하는 것 같아, 문제는 **? ** 같은 유형과 일치하지 않지만 여전히 모르겠다는 것입니다 그것을 해결하는 방법. 각 컨테이너 cl 호환 가능한 키 유형을 가진 다른 컨테이너와 비교할 수 있습니다. –

답변

0

을 소비 할 수있는 몇 가지 키를 생성 할 수있는 Container을해야하지만 해킹과 같습니다

private static class Container 
    <K extends Comparable<? super K>, Value> 
    implements Comparable<Container<? extends Comparable<? super K>, ?>> 
    { 
     public K key; 
     public Value value; 
     public Container(K k, Value v) { 
      key = k; 
      value = v; 
     } 
     public int compareTo(Container<? extends Comparable<? super K>, ?> o) { 
      return -o.key.compareTo(key); 
     } 
    } 

내가 확실히 key.compareTo(o.key)를 작성하는 것을 선호하지만 그게 필요한 일반 제약을 작성 관리하지 않았다 ... :(

1

:

private static class Container 
    <Key extends Comparable<? super Key>, Value> 
    implements Comparable<Container<? super Key, ?>> 
    { 
     public Key key; 
     public Value value; 
     public Container(Key k, Value v) { 
      key = k; 
      value = v; 
     } 
     public int compareTo(Container<? super Key, ?> o) { 
      return key.compareTo(o.key); 
     } 
    } 
    ... 

는 오류입니다. ContainerComparable<Pair<? super Key, Value>을 구현하는 것으로 정의합니다. 즉, 메소드를 선언해야 함을 의미합니다.

public int compareTo(Comparable<Pair<? super Key, Value> o) 

와일드 카드가 없기 때문에 지금은 그렇지 않습니다.

넓은 의미에서 문제는 와일드 카드 일치입니다. ?은 "이 범위와 일치하는 모든 유형"을 의미합니다. 비판적으로 ?의 다른 인스턴스는 다른 구체적인 유형이 될 수 있습니다; 이것은 "캡처"유형이 참조하는 것입니다.

물음표가 "쌍으로 표시"될 때마다 해당 매개 변수의 이름을 지정하여 ID를 적용 할 수 있습니다 (예 : 메소드의 일반 매개 변수 소개). ?을 사용할 때마다 본질적으로 "나는 모두이 매개 변수의 구체적인 유형이 무엇인지 신경 쓰지 않습니다."라고 말하면서 정확히 일치하는 매개 변수에 의존하는 작업을 수행 할 수 없습니다 (예 : 할당).


편집 : 귀하의 의도가 약간 벗어난 것 같습니다. 특정 Key 유형의 ContainerKey의 다른 (수퍼 클래스) 컨테이너와 비교하여 선언하려고했습니다. 나는 이것이 반드시 비대칭을 가져 오기 때문에 반드시 좋은 생각이라고 확신하지는 않습니다.

예를 들어 Container<String>Container<Object>과 비교할 수 있도록하려고합니다. 하지만 다른 방법으로 라운드를 비교해도 을 컴파일하지 않았을 것입니다. 이 상황이 당신에게 유효한 것 같습니까? 비교 가능성이 대칭 적이라고 기대할 수 있으며 a.compareTo(b)이 1이지만, b.compareTo(a)이 아니라 -1을 반환하지만 컴파일하는 것을 거부합니다. 이것이 Double이 예를 들어 Comparable<Double>이고 Comparable<? super Double>이 아닌 이유입니다.

평이한 대답은 EDIT : 임의의 개체와 비교할 수 없으므로 이러한 와일드 카드를 제거해야합니다. 당신이 Comparable 유형을 생성하지만 이해하지 않는 경우 어떤 이유

private static class Container 
<Key extends Comparable<Key>, Value> 
implements Comparable<Container<Key, ?>> 
{ 
    ... 

    public int compareTo(Container<Key, ?> o) { 
     return key.compareTo(o.key); 
    } 
} 
+0

매개 변수에 이름을 정확히 지정하려면 어떻게해야합니까? –

+0

'private 정적 클래스 MyStructure , 값>은 새 매개 변수 유형 'T'를 정의합니다. –

+0

' private 메소드 (Comparable >)'와 같은 메소드를 선언하십시오. 이렇게하면 Comparable >는 일치 할 것이지만 이제는 메소드 전체에서 사용할 수있는'T' 라벨을 가지고 있습니다. 'T'에 대한 여러 참조는 항상 같은 유형을 나타내며 '?'에 대한 여러 참조와 달리 항상 다른 유형을 나타냅니다. –

-3

, 이클립스 삽입 "슈퍼 유형을?"따라서 정의는 같을 것이다 (유형의 슈퍼 클래스가 compareTo()에서 작동합니다?) .

"? super"를 제거하면 컴파일됩니다.

5

PECS : Producer extends, Consumer super.

compareTo 메소드에서 뒤로 작업 해 봅시다. 컨테이너와 비교하기를 원하고 키를 사용하여 비교하려고합니다 (따라서 키.compareTo (o.key)). 즉 oKey이고, keyKey이어야합니다. 첫 번째 부분은 메소드 선언이 public int compareTo(Container<? extends Key, ?> o)이어야 함을 의미하며 이는 Comparable<Container<? extends Key, ?>>을 구현해야 함을 의미합니다. 두 번째 부분은 KeyComparable<? super Key>이어야 함을 의미합니다.

private static class Container<Key extends Comparable<? super Key>, Value> 
        implements Comparable<Container<? extends Key, ?>> { 

    public Key key; 
    public Value value; 

    public Container(Key k, Value v) { 
     key = k; 
     value = v; 
    } 

    public int compareTo(Container<? extends Key, ?> o) { 
     return key.compareTo(o.key); 
    } 
} 

편집 : 정확히 아래의 의견에 따라, 선언은 다음과 것이다. compareTo를 호출하는 키의 플립 (flip)과 더 이상 comparable을 구현할 필요가없는 Key의 차이점을 확인하십시오. 당신은이 작동하는 Key

private static class Container<Key, Value> implements 
     Comparable<Container<? extends Comparable<? super Key>, ?>> { 

    //fields and constructors... 

    public int compareTo(Container<? extends Comparable<? super Key>, ?> o) { 
     return -o.key.compareTo(key); 
    } 
} 
+0

나는 이것에 완전히 동의하지 않는다. 그러나 아마도 나는 그것을 이해하지 못했다. 내가 본대로, 당신의'Container'는 첫 번째 키의 키에서 파생 된 * 키를 가진 다른 컨테이너와 비슷합니다. contaner가 첫 번째 키의 키와 비슷한 * 키를 가진 다른 컨테이너와 비교할 수 있기를 원했습니다. –

+0

@Helltone : 다른 하나의 키가 첫 번째 키의 키와 비교되기를 원한다면, 첫 번째 키의 키는 실제로는 비교할 필요가 없습니다. 위의 답변을 수정했습니다. – ILMTitan

+0

이것은 내가 게시 한 답변에서 내가 한 일이지만 실제로는 ** - o. **'key.compareTo'에 만족하지 않습니다. –