2012-05-02 1 views
1

저는 크리켓 팀 플레이어를 저장하고 주문하기 위해 ArrayList를 사용했습니다. 중복 제거의 이점 때문에 TreeSet 사용에 대해 생각하기 시작했습니다. 나는 데 문제가 예를 들어, 나는 다음과 같은 두 선수 만드는 경우이다 그러나 : 두 선수가 같은 이름과 성을 가지고TreeSet에서 중복 제거

P p1 = new P("Jack","Daniel",33(age),180(height),78(weight),41(games played),2300 
(runs scored),41(dismisses)) 
P p2 = new P("Jack","Daniel",37(age),185(height),79(weight),45(games played),2560 
(runs scored),45(dismisses)) 

공지 사항을하지만, 다른 모든 다르다. 이 두 플레이어를 TreeSet에 추가하려고하면 이름이 유사하기 때문에 중복 된 것으로 간주하고 두 번째 플레이어는 제거합니다. 분명히 나는 ​​이런 일이 일어나기를 원하지 않으며, 그가 가지고있는 모든 것이 다른 플레이어와 동일하고 오직 성과 이름이 아니라면 세트를 제거하기를 원합니다.

이 방법이 있습니까?

또한 내 TreeSet은 Player 객체를 사용합니다.

답변

11

원래이 답변은 TreeSetequals()이 아닌 compareTo()을 기반으로 비교를 수행한다는 사실을 간과했습니다. 이 문제를 해결하기위한 편집이 이루어졌습니다.

당신은 제대로 Player 개체에 대한 equals(), hashCode()compareTo()를 정의 할 필요가있다. (이 hashCode()를 구현하는 TreeSet 아닌 HashSet을 이래로 그렇게 중요하지 않다 -하지만 좋은 방법입니다.)

같음와 hashCode 계정에 모든 필드를 취할 필요가있다. 이클립스는 이와 비슷한 모양을 자동으로 생성 할 수 있습니다 (소스> 생성 해시 코드 및과 동일). 이미 모든 필드를 사용하지 않는 자연 정렬 순서이있는 경우

, 당신은 당신 TreeSet에 사용자 정의 비교를 제공 할 수 있습니다. 그러나 실제로 필드의 하위 집합을 기준으로 정렬하려는 경우에도 모든 필드별로 정렬하는 것을 막을 수는 없습니다 (흥미로운 부분은 일부만 재생 됨). 여기서 주목해야 할 중요한 점은 TreeSetequals() 메서드가 아닌 동등성을 결정하지만 compareTo() == 0입니다.

@Override 
public boolean equals(Object obj) 
{ 
    if (this == obj) { 
    return true; 
    } 
    if (obj == null) { 
    return false; 
    } 
    if (getClass() != obj.getClass()) { 
    return false; 
    } 

    Player that = (Player) obj; 
    return this.age == that.age && 
     this.height == that.height && 
     this.weight == that.weight && 
     this.games == that.games && 
     this.runs == that.runs && 
     this.dismisses == that.dismisses && 
     this.given.equals(that.given) && 
     this.family.equals(that.family); 
} 

그리고 여기 해시 코드입니다 : 여기

가) (예를 들어 같음의 마지막

@Override 
public int hashCode() { 
    final int prime = 31; 
    int result = 1; 
    result = prime * result + this.age; 
    result = prime * result + this.dismisses; 
    result = prime * result + this.family.hashCode()); 
    result = prime * result + this.games; 
    result = prime * result + this.given.hashCode()); 
    result = prime * result + this.height; 
    result = prime * result + this.runs; 
    result = prime * result + this.weight; 
    return result; 
} 

, 여기 compareTo와는 다음과 같습니다

public int compareTo(Player that) 
{ 
    int result; 

    result = this.family.compareTo(that.family); 
    if (result != 0)        // is the family name different? 
    { 
    return result;        // yes ... use it to discriminate 
    } 

    result = this.given.compareTo(that.given); 
    if (result != 0)        // is the given name different? 
    { 
    return result;        // yes ... use it to discriminate 
    } 

    result = this.age - that.age;     // is the age different? 
    if (result != 0) 
    { 
    return result;        // yes ... use it to discriminate 
    } 

    ... (and so on) ... 
    ... with the final one ... 

    return this.dismisses - that.dismisses;  // only thing left to discriminate by 
} 
+0

나를 도와 줄 수있는 예가 있습니까? –

+0

플레이어를 이름과 ID로 정렬하는 compareTo 메서드가 있습니다 –

+0

이 경우 compareTo 메서드에서 점수를 매기거나 실행 한 게임과 같은 다른 필드를 사용해야합니까? –

0

수준의 학생에 Comparable {

를 구현
String name; 

public Student(String name) { 
    this.name=name; 

} 

public String toString(){ 
    return name; 
} 

public int compareTo(Student gStudent) { 
    if(!this.name.equals(gStudent.getName())) 
     return 1; 
    return 0; 
} 

private String getName() { 
    return name; 
}