2017-01-13 18 views
5

У меня есть следующий код, который сортирует Employees's на основе их опыта.Данные, потерянные из TreeSet при использовании компаратора

Я добавил 2 сотрудников с различными name и теми же experience. Я ожидаю, что в конце set будет работать 2 сотрудника, но я получаю только один.

Я также переопределил equals и hashcode, может ли кто-нибудь сказать мне, почему я получаю только одного сотрудника в комплекте.

испытаний Класс

import java.util.Comparator; 
import java.util.Set; 
import java.util.TreeSet; 

import org.apache.commons.lang3.builder.EqualsBuilder; 
import org.apache.commons.lang3.builder.HashCodeBuilder; 
import org.junit.Test; 

public class SetWithComparator { 


    @Test 
    public void testComparatorWithSet() { 

     Comparator<Employee> comparator = 
       (emp1, emp2) -> emp1.getYearOFExp().compareTo(emp2.getYearOFExp()); 

     Set<Employee> empSet = new TreeSet<>(comparator); 

     Employee e1 = new Employee(); 
     e1.setName("Employee-1"); 
     e1.setYearOFExp(12f); 

     Employee e2 = new Employee(); 
     e2.setName("Employee-2"); 
     e2.setYearOFExp(12f); 

     empSet.add(e1); 
     empSet.add(e2); 

    } 

} 

Модель Класс

class Employee { 


    private String name; 
    private Float yearOFExp; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public Float getYearOFExp() { 
     return yearOFExp; 
    } 

    public void setYearOFExp(Float yearOFExp) { 
     this.yearOFExp = yearOFExp; 
    } 

    @Override 
    public boolean equals(Object obj) { 

     if (obj instanceof Employee) { 

      Employee e = (Employee) obj; 
      return new EqualsBuilder().append(name, e.getName()).isEquals(); 
     } else { 
      return false; 
     } 

    } 

    @Override 
    public int hashCode() { 
     return new HashCodeBuilder().append(name).toHashCode(); 
    } 

} 

ответ

3

Для SortedSetComparator определяет, какие элементы являются одинаковыми, и он не будет содержать дубликатов.Если вы не хотите, чтобы рассмотреть все сотрудник с таким же опытом, чтобы быть таким же, вы должны добавить дополнительный заказ:

Comparator<Employee> comparator = Comparator.comparing(Employee::getYearOFExp) 
              .thenComparing(Employee::getName); 

Обратите внимание, что вы должны включать все свойства, которые составляют личность сотрудник. В вашем примере есть только имя, однако в реальных сценариях у вас будет больше. С другой стороны, если у вас есть идентификатор, который определяет личность, вам не нужно проверять другие свойства, и, фактически, не должен, так как большинство свойств, включая имя, могут быть изменены. Это также относится к реализации equals и hashCode.

Чтобы предупредить о ложных предположениях о том, что можно считать предоставленным, гендерные изменения являются реальным фактом жизни, и даже дни рождения могут оказаться ложными и нуждаться в исправлении.

8

Поскольку компаратор не согласуется с методом Equals. Пожалуйста, проверьте документацию Comparator.

Упорядочение налагается компаратор с на множестве элементов S, как говорит , чтобы быть совместимыми с равными тогда и только тогда, когда c.compare (е1, е2) == 0 имеет то же логическое значение, как e1 .equals (e2) для каждого e1 и e2 в S.

следует проявлять осторожность при использовании компаратора, способного устанавливающего порядка несовместимым с равными по заказу отсортированного набора (или отсортированной карты). Предположим, что отсортированный набор (или отсортированная карта) с явным сопоставителем c используется с элементами (или ключами), взятыми из набора S. Если порядок, наложенный c на S, несовместим с равными, отсортированный набор (или отсортированный карта) будет вести себя «странно». В частности, отсортированный набор (или отсортированная карта) нарушит общий контракт для набора (или карты ), который определяется в терминах равных.

Точное поведение, которое вы испытываете намекают в документации о Comparable (хотя вы используете компаратор):

Например, если один добавляет два ключа а и Ь, что (a.equals! (b) & & a.compareTo (b) == 0) в сортированный набор, который не использует явный сопоставитель , вторая операция добавления возвращает значение false (и размер сортированный набор не увеличивается), поскольку и b эквивалентны с перспективой сортированного набора.

В вашем случае: comparator.compare(e1, e2) является 0, e1.equals(e2) является false.

+0

спасибо за ответ – Jobin