2016-12-06 7 views
-1

어떤 이유인지 내 비교자가 내 트리 집합에 허용되지 않습니다. 도와주세요?Java Treeset : "생성자를 해결할 수 없다"(비교 자용)

TreeSet의 클래스 :

public class PQTreeQueue<Integer> extends AbstractQueue<Integer>{ 

private TreeSet<Integer> _pqTree; 

public PQTreeQueue() { 
    noZeroComparator noZero = new noZeroComparator(); 
    _pqTree = new TreeSet<Integer>(noZero); 
} 

비교기 클래스 (다른 파일에 정의)

public class noZeroComparator implements Comparator<Integer> { 

@Override 
public int compare(Integer e0, Integer e1) { 
    if (e0.compareTo(e1) >= 0) { 
     return -1; 
    } else { 
     return 1; 
    } 
} 
+1

참고 : 0을 반환하지 않는 비교기는 유효한 비교자가 아닙니다. 난 당신이 0을 결코 돌려주지 않는 비교자를 써서 당신이 달성하는 것을 시도하고있는 무슨을 모른다, 그러나 문제를 일으킬 것이다. – ajb

+0

이것이 올바른 비교자가 아닌 이유를 설명하는 메모에 답변을 추가했습니다. – ajb

답변

0

당신은 정수로 일반적인 매개 변수 TreeSet을 정의했다. 지정한 TreeSet 생성자에는 comparator이 필요합니다. 일반 매개 변수는 수퍼 유형의 정수 또는 정수입니다. 그 생성자의 정의 : -

TreeSet<E>(comparator<? super E>); 

그래서 더 나은 당신이 TreeSet에 일반적인 매개 변수로 정수를 전달하지 않습니다. Integer과 같은 클래스를 만든 다음 comparator을 자신의 클래스로 사용하여 comparator에 만들고 사용자 정의 정수 클래스에 대한 일반 매개 변수와 동일한 클래스를 만듭니다.

public class MyInterger { 
    int value = 0; 

     public int compareTo(MyInterger anotherInteger) { 
      return compare(this.value, anotherInteger.value); 
     } 

     public static int compare(int x, int y) { 
      return (x < y) ? -1 : ((x == y) ? 0 : 1); 
     } 
} 


public class noZeroComparator implements Comparator<MyInterger> { 

@Override 
public int compare(MyInterger e0, MyInterger e1) { 
    if (e0.compareTo(e1) >= 0) { 
     return -1; 
    } else { 
     return 1; 
    } 
} 

} 



public class PQTreeQueue<MyInterger> extends AbstractQueue<MyInterger>{ 

private TreeSet<MyInterger> _pqTree; 

public PQTreeQueue() { 

    noZeroComparator noZero = new noZeroComparator(); 
    _pqTree = new TreeSet<MyInterger>(noZero); 
} 
+0

정답이 아닙니다. – ajb

+0

왜 그렇습니까? 사용자가 사용자 지정 비교를 원한다면 0이나 -1 또는 1을 반환하지 않으려 고합니다. 코드에서이를 얻을 수 있습니까? – vvtx

+0

설명을 신경 쓰지 않고 아래로 투표 하시겠습니까? 쿨하지 않아. – vvtx

0

에러이 라인이다

public class PQTreeQueue<Integer> extends AbstractQueue<Integer> 

이 (처음 부분)이 일반 클래스를 선언하기위한 구문이다. 제네릭 클래스를 선언 할 때 꺾쇠 괄호 안에있는 식별자는 유형 매개 변수 입니다. 그것은 단지 당신이 당신의 유형 매개 변수 Integer 대신 E의라는 점을 제외

public class ArrayList<E> ... 

자바

의 선언처럼. 컴파일러는 IntegerE을 처리하는 것과 같은 방식으로 취급합니다. 실제 형식으로 바꿀 수있는 형식 매개 변수가되고, Integer이라는 이름이 Java의 다른 것들에 사용된다는 사실은 의미가 없습니다. 제네릭 유형은 모든 연결이 Integer으로 끊어집니다. 그리고이 클래스의 다른 곳에서는 Integer은 실제 변수가 아닌 변수 유형을 나타냅니다. java.lang.Integer.

당신이 <Integer>을 제거하는 경우 :

public class PQTreeQueue extends AbstractQueue<Integer> 

모든 것이 작동합니다. (.?을 제외하고는 compare(x, x)를 호출하는 경우 0이 작동하지 않습니다 반환하지 비교기는 무슨 일이 일어날 것이라는 사실이 x > x 말할 것입니까?) 비교기의 요구 사항에

정보 : 수학 규칙은 비교자가 전체 순서를 부과한다는 것입니다. 즉, 함수는 전체 순서 (규칙 성 포함)에 대한 규칙을 따라야합니다. the javadoc for compare()에 따르면 "구현자는 모든 x와 y에 대해 sgn(compare(x, y)) == -sgn(compare(y, x))을 보장해야합니다." 이는 특히 sgn(compare(x,x)) == -sgn(compare(x,x))을 의미하며 compare(x,x) == 0 인 경우에만 가능합니다. 이것은 compare이 두 인수가 모두 == 일 때 0을 반환해야하므로 0을 반환하지 않는 비교기가 규칙을 위반 함을 증명합니다. [==이 아니지만 .equals()에 따라 동일한 인수에 대해서는 규칙이 약합니다. javadoc은 그것을하지 않아야한다고 말하지 않지만, 그것은 정렬 된 세트와 맵 같은 것들이 이상하게 행동 할 수 있다고 말한다.http://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html.]