2016-09-15 87 views
2

我有一个Employee对象,其中包含两个字段namejobTitle。对于员工对象进行排序,如果jobTitle为空,那么优先级应该是jobTitle,然后排序应该基于名称。基于对象的不同可空字段的比较器

下面是Employee对象

public class Employee { 
    private String name; 
    private String jobTitle; 
} 

我用链比较与JobTitlecomparatorNameComparator来实现这一目标:

public class EmployeeChainedComparator implements Comparator<Employee> { 

    private List<Comparator<Employee>> listComparators; 

    @SafeVarargs 
    public EmployeeChainedComparator(Comparator<Employee>... comparators) { 
     this.listComparators = Arrays.asList(comparators); 
    } 

    @Override 
    public int compare(Employee emp1, Employee emp2) { 
     for (Comparator<Employee> comparator : listComparators) { 
      int result = comparator.compare(emp1, emp2); 
      if (result != 0) { 
       return result; 
      } 
     } 
     return 0; 
    } 
} 

public class EmployeeJobTitleComparator implements Comparator<Employee> { 

    @Override 
    public int compare(Employee emp1, Employee emp2) { 
     if(emp1.getJobTitle() != null && emp2.getJobTitle() != null){ 
      return emp1.getJobTitle().compareTo(emp2.getJobTitle()); 
     } else { 
      return 0; 
     } 
    } 
} 

public class EmployeeNameComparator implements Comparator<Employee> { 

    @Override 
    public int compare(Employee emp1, Employee emp2) { 
     return emp1.getName().compareTo(emp2.getName()); 
    } 
} 

public class SortingMultipleAttributesExample { 
    public static void main(String[] args) { 
     List<Employee> listEmployees = new ArrayList<Employee>(); 
     listEmployees.add(new Employee("Tom", "Developer")); 
     listEmployees.add(new Employee("Sam", null)); 
     listEmployees.add(new Employee("Tim", "Designer")); 
     listEmployees.add(new Employee("Bob", null)); 
     listEmployees.add(new Employee("Peter", null)); 
     listEmployees.add(new Employee("Craig", "Programmer")); 

     Collections.sort(listEmployees, new EmployeeChainedComparator(new EmployeeJobTitleComparator(), new EmployeeNameComparator() 
       )); 

     for(Employee emp : listEmployees){ 
      System.out.println("Employee Job: "+emp.getJobTitle()+" Employee Name: "+emp.getName()); 
     } 
    } 
} 

现在,我应该得到的输出这样

Employee Job: Designer Employee Name: Tim 
Employee Job: Developer Employee Name: Tom 
Employee Job: Programmer Employee Name: Craig 
Employee Job: null Employee Name: Bob 
Employee Job: null Employee Name: Peter 
Employee Job null Employee Name: Sam 

但我没有达到预期的效果。我得到这样的输出

Employee Job Developer Employee Name Tom 
Employee Job null Employee Name Sam 
Employee Job Designer Employee Name Tim 
Employee Job null Employee Name Bob 
Employee Job null Employee Name Peter 
Employee Job Programmer Employee Name Craig 

任何人都可以帮助我如何做到这一点?

+0

你得到了什么输出? – Eran

+0

获取输出像这样的员工招聘开发员工姓名汤姆 员工招聘空员工姓名山姆 员工招聘设计师员工姓名添 员工招聘空员工姓名鲍勃 员工招聘空员工姓名彼得 员工招聘程序员雇员姓名克雷格 – Digital

+0

不知道如果这是整个问题,但调用“EmployeeChainedComparator”的构造函数只传递'EmployeeJobTitleComparator'。尝试添加'EmployeeNameComparator',以便它包含在列表中。 –

回答

2

如果标题任null,那么这两个Employee旨意评估,平等相待,即使其中的一个不为空。这不是你想要的。您希望所有null标题彼此相等,但不是非空值。

这个替换您的比较方法:

public int compare(Employee emp1, Employee emp2) { 
    if(emp1.getJobTitle() == null && emp2.getJobTitle() == null){ 
     return 0; 
    } 
    if(emp1.getJobTitle() == null) return 1; 
    if(emp2.getJobTitle() == null) return -1; 
    return emp1.getJobTitle().compareTo(emp2.getJobTitle()); 
} 

,你应该得到你所期望的结果。

+0

谢谢@resueman我得到了预期的输出与上面的代码 – Digital

6

由于您使用的是Java 8,因此您可以使用内置比较器工具而不是创建自己的比较器。比较职务,然后名称可以很容易地

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

做如何处理null值也内置了与nullsLastnullsFirst方法。这些方法将现有的比较器封装到安全比较器中,在结束时或开始时将值放入null

因此,你可以有:

import static java.util.Comparator.comparing; 
import static java.util.Comparator.naturalOrder; 
import static java.util.Comparator.nullsLast; 

// ... 

Comparator<Employee> comparator = 
    comparing(Employee::getJobTitle, nullsLast(naturalOrder())).thenComparing(Employee::getName); 

Collections.sort(listEmployees, comparator); 

比较由comparing创建的职称与null安全比较将最后(see alsonull值。对于相同的标题,这是雇员的名字thenComparing