2015-07-10 2 views
0

Я создал класс Student как это:Понимание TreeSet когда CompareTo возвращает 0

public class Student implements Comparable<Student> { 

    private String firstName; 
    private String lastName; 

    public Student(String firstName, String lastName) { 
     this.firstName = firstName; 
     this.lastName = lastName; 
    } 

    // Getters & Setters follow here... 

    @Override 
    public int compareTo(Student student) { 
     int hash = this.firstName.compareTo(student.firstName); 
     return hash; 
    } 

    @Override 
    public String toString() { 
     return "Student [firstName=" + firstName + ", lastName=" + lastName 
       + "]"; 
    } 

} 

Это мой тестовый класс, где я просто добавить элементы к моему TreeSet:

public class SortedSetExample1 { 
    public static void main(String[] args) { 
     SortedSet<Student> set = new TreeSet<Student>(); 
     set.add(new Student("A1","A2")); 
     set.add(new Student("B1","B2")); 
     set.add(new Student("A1","B2")); 
     set.add(new Student("A2","B2")); 
     System.out.println(set); 
    } 
} 

Согласно моей программе выход:

[Student [firstName=A1, lastName=A2], Student [firstName=A2, lastName=B2], Student [firstName=B1, lastName=B2]] 

в моем тестовом классе я добавляю Student объекты TreeSet, а также я не переопределил hashCode & equals методов. Поэтому я ожидал, что TreeSet будет содержать все 4 объекта, но я также могу видеть, что он содержит 3 объекта. Не могли бы вы объяснить, почему new Student("A1","B2") не является частью моего TreeSet?

Также согласно Java docs for TreeSet здесь, он говорит:

Добавляет указанный элемент к этому набору, если он уже не присутствует. Более формально добавляет указанный элемент e к этому набору, если в наборе не содержится элемента e2, для которого (e == null? E2 == null: e.equals (e2)). Если этот набор уже содержит элемент, вызов оставляет значение без изменений и возвращает false.

Как я не переопределил метод equals, то почему в коллекции нет всех четырех элементов?

+0

Я думаю, что это из-за вашего 'compareTo()' .. – Gosu

+0

@Gosu, compareTo просто сравнивает на основе 'firstName', но почему мне не разрешено добавлять 2 объекта, имеющих одно имя firstName, но разные lastNames? – user3181365

+0

Возможный дубликат [Java, Почему подразумевается, что объекты равны, если compareTo() возвращает 0?] (Http://stackoverflow.com/questions/7229977/java-why-it-is-implied-that-objects- является равным, если-CompareTo возвраты-0) – meskobalazs

ответ

6

В java.util.TreeSet говорит:

экземпляр TreeSet выполняет все сравнения элементов, используя его СотрагеТо метод (или сравнить), так что два элемента, которые считаются равными этим методом, с точки зрения множества, равна

Kudos to @Jon Skeet.

-1

Ну, ваши значения ключей деревьев - «A1», «B1», «A1», «A2». Несмотря на то, что вы не превышаете равные и хэш-коды, хэш-код по умолчанию для «A1» будет таким же, и, следовательно, деревья будут рассматривать этот ключ как дубликат, так что вы не сможете ввести «A1», «B2»

1

Это связано с тем, что TreeSet использует compareTo (или Comparator.compare), чтобы проверить, равны ли два элемента. Об этом говорят документы.

Обратите внимание, что порядок, поддерживаемый набором (будь то явный компаратор), должен быть согласован с равными, если он правильно реализует интерфейс Set. (См. Comparable или Comparator для точного определения соответствия с равными.) Это происходит потому, что интерфейс Set определен в терминах операции equals, но экземпляр TreeSet выполняет все сравнения элементов с помощью метода compareTo (или сравнения), поэтому два элементы, которые по этому методу считаются равными, равны, с точки зрения множества. Поведение множества хорошо определено, даже если его упорядочение не соответствует равным; он просто не подчиняется генеральному контракту интерфейса Set.

0

Поскольку вы сравнили только первое имя в методе CompareTo, вам нужно

@Override 
public int compareTo(Student student) { 
    int comp = this.firstName.compareTo(student.firstName); 
    if(comp==0) return this.lastName.compareTo(student.lastName); 
    return comp; 
} 

когда CompareTo возвращает 0, TreeSet предполагает, что его дубликат.

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