Dig*_*tal 3 java comparator java-8
我有一个Employee包含两个字段的对象name和jobTitle.对于员工对象的排序,首先应该打开jobTitle,如果jobTitle为null,则排序应该基于名称.
下面是Employee对象
public class Employee {
private String name;
private String jobTitle;
}
Run Code Online (Sandbox Code Playgroud)
我用链式比较与JobTitlecomparator和NameComparator实现这一目标:
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());
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在我应该得到这样的输出
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
Run Code Online (Sandbox Code Playgroud)
但是我没有像我预期的那样得到理想的结果.我得到这样的输出
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
Run Code Online (Sandbox Code Playgroud)
任何人都可以帮我解决这个问题吗?
Tun*_*aki 10
由于您使用的是Java 8,因此可以使用内置的比较器设备,而不是创建自己的比较器.比较职位和名称可以很容易地完成
Comparator<Employee> comparator =
Comparator.comparing(Employee::getJobTitle).thenComparing(Employee:getName);
Run Code Online (Sandbox Code Playgroud)
如何处理null值也是使用nullsLast和nullsFirst方法内置的.这些方法将现有比较器封装到null安全比较器中,将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);
Run Code Online (Sandbox Code Playgroud)
比较器由comparing作业标题创建,null安全比较器将null值设置为最后(另请参见).对于相同的标题,它是thenComparing员工的名字.
如果任一标题为null,则这两个Employees 的计算结果将相等,即使其中一个不为空。那不是你想要的。您希望所有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());
}
Run Code Online (Sandbox Code Playgroud)
您应该会得到您期望的结果。
| 归档时间: |
|
| 查看次数: |
911 次 |
| 最近记录: |