2012-05-02 6 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, он считает их дублирующими из-за сходства имен и удаляет второй. Очевидно, я не хочу, чтобы это произошло, и я хочу, чтобы Set удалял игрока, только если все, что у него есть, такое же, как у другого игрока, а не только имя и фамилия.

Есть ли способ достичь этого?

Также мой TreeSet принимает объект Player.

ответ

11

Первоначально этот ответ игнорировал тот факт, что TreeSet выполняет свои сравнения на основе compareTo(), а не equals(). Для этого были сделаны изменения.

Необходимо определить equals(), hashCode() и compareTo() для вашего Player объекта правильно. (Так как это TreeSet и не HashSet, реализующий hashCode() не так уж важно - но это хорошая практика.)

Равно и хэш-код, необходимо принимать во внимание все поля. Eclipse может автоматически генерировать один для вас, который будет выглядеть примерно так (Источник> Генерировать хэш-код и равен).

Если у вас уже есть естественный порядок сортировки, который не использует все поля, тогда вы можете поставить пользовательский компаратор к вашему TreeSet. Однако даже если вы действительно хотите сортировать по подмножеству полей, вам нечего останавливать сортировку по всем полям (с неинтересными полями, которые играют только часть интересных частей, идентичны). Важно отметить, что TreeSet определяет равенство не методом equals(), а 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

У меня есть метод compareTo, который сортирует игроков по именам и идентификаторам –

+0

Нужно ли использовать другие поля, такие как игры, забитые и т. Д. В методе compareTo? –

0

класс Student реализует Сопоставимые {

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; 
} 

Смежные вопросы