Java Comparator接口使用教程

x33g5p2x  于2021-08-21 转载在 Java  
字(8.4k)|赞(0)|评价(0)|浏览(433)

1. Comparator接口的概述

我们在前面的指南中学习的Comparable接口为一个类的对象定义了一个默认排序。这个默认排序也被称为对象的自然排序。

如果你想对一些对象进行自然排序以外的排序呢?或者,如果你想对一些没有实现Comparable的对象进行排序呢?要做这两件事,你需要提供一个Comparator--一个封装了排序的对象。与Comparable 接口一样,Comparator接口由一个方法组成。

public interface Comparator<T> {
    int compare(T o1, T o2);
}

compare()方法的实现应该返回

*一个negative整数,如果第一个参数小于第二个参数。

  • zero,如果第一个参数等于第二个参数,以及
  • 一个positive整数,如果第一个参数大于第二个参数。
    如果其中一个参数的类型对比较器来说不合适,比较方法就会抛出一个ClassCastException

2. Comparator使用示例

让我们看看如何通过定义不同的Comparators来对我们在上一节中定义的Employee对象集合根据不同的字段进行排序。

例1:按姓名对雇员进行排序

List<Employee> employees = new ArrayList<>();

employees.add(new Employee(1010, "Rajeev", 100000.00, LocalDate.of(2010, 7, 10)));
employees.add(new Employee(1004, "Chris", 95000.50, LocalDate.of(2017, 3, 19)));
employees.add(new Employee(1015, "David", 134000.00, LocalDate.of(2017, 9, 28)));
employees.add(new Employee(1009, "Steve", 100000.00, LocalDate.of(2016, 5, 18)));

System.out.println("Employees : " + employees);

// Sort employees by Name
Collections.sort(employees, Comparator.comparing(Employee::getName));
System.out.println("\nEmployees (Sorted by Name) : " + employees);

例2:按工资对雇员进行排序

List<Employee> employees = new ArrayList<>();

employees.add(new Employee(1010, "Rajeev", 100000.00, LocalDate.of(2010, 7, 10)));
employees.add(new Employee(1004, "Chris", 95000.50, LocalDate.of(2017, 3, 19)));
employees.add(new Employee(1015, "David", 134000.00, LocalDate.of(2017, 9, 28)));
employees.add(new Employee(1009, "Steve", 100000.00, LocalDate.of(2016, 5, 18)));

// Sort employees by Salary
Collections.sort(employees, Comparator.comparingDouble(Employee::getSalary));
System.out.println("\nEmployees (Sorted by Salary) : " + employees);

例3:按入职日期对员工进行排序

List<Employee> employees = new ArrayList<>();

employees.add(new Employee(1010, "Rajeev", 100000.00, LocalDate.of(2010, 7, 10)));
employees.add(new Employee(1004, "Chris", 95000.50, LocalDate.of(2017, 3, 19)));
employees.add(new Employee(1015, "David", 134000.00, LocalDate.of(2017, 9, 28)));
employees.add(new Employee(1009, "Steve", 100000.00, LocalDate.of(2016, 5, 18)));

// Sort employees by JoiningDate
Collections.sort(employees, Comparator.comparing(Employee::getJoiningDate));
System.out.println("\nEmployees (Sorted by JoiningDate) : " + employees);

例4:按姓名降序对员工排序

List<Employee> employees = new ArrayList<>();

employees.add(new Employee(1010, "Rajeev", 100000.00, LocalDate.of(2010, 7, 10)));
employees.add(new Employee(1004, "Chris", 95000.50, LocalDate.of(2017, 3, 19)));
employees.add(new Employee(1015, "David", 134000.00, LocalDate.of(2017, 9, 28)));
employees.add(new Employee(1009, "Steve", 100000.00, LocalDate.of(2016, 5, 18)));

// Sort employees by Name in descending order
Collections.sort(employees, Comparator.comparing(Employee::getName).reversed());
System.out.println("\nEmployees (Sorted by Name in descending order) : " + employees);

例5:串联多个比较器

List<Employee> employees = new ArrayList<>();

employees.add(new Employee(1010, "Rajeev", 100000.00, LocalDate.of(2010, 7, 10)));
employees.add(new Employee(1004, "Chris", 95000.50, LocalDate.of(2017, 3, 19)));
employees.add(new Employee(1015, "David", 134000.00, LocalDate.of(2017, 9, 28)));
employees.add(new Employee(1009, "Steve", 100000.00, LocalDate.of(2016, 5, 18)));

// Chaining multiple Comparators
// Sort by Salary. If Salary is same then sort by Name
Collections.sort(employees, Comparator.comparingDouble(Employee::getSalary)
                            .thenComparing(Employee::getName));
System.out.println("\nEmployees (Sorted by Salary and Name) : " + employees);

3. 完整的例子供参考

import java.time.LocalDate;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ComparatorExample {
    public static void main(String[] args) {
        List<Employee> employees = new ArrayList<>();

        employees.add(new Employee(1010, "Rajeev", 100000.00, LocalDate.of(2010, 7, 10)));
        employees.add(new Employee(1004, "Chris", 95000.50, LocalDate.of(2017, 3, 19)));
        employees.add(new Employee(1015, "David", 134000.00, LocalDate.of(2017, 9, 28)));
        employees.add(new Employee(1009, "Steve", 100000.00, LocalDate.of(2016, 5, 18)));

        System.out.println("Employees : " + employees);

        // Sort employees by Name
        Collections.sort(employees, Comparator.comparing(Employee::getName));
        System.out.println("\nEmployees (Sorted by Name) : " + employees);

        // Sort employees by Salary
        Collections.sort(employees, Comparator.comparingDouble(Employee::getSalary));
        System.out.println("\nEmployees (Sorted by Salary) : " + employees);

        // Sort employees by JoiningDate
        Collections.sort(employees, Comparator.comparing(Employee::getJoiningDate));
        System.out.println("\nEmployees (Sorted by JoiningDate) : " + employees);

        // Sort employees by Name in descending order
        Collections.sort(employees, Comparator.comparing(Employee::getName).reversed());
        System.out.println("\nEmployees (Sorted by Name in descending order) : " + employees);

        // Chaining multiple Comparators
        // Sort by Salary. If Salary is same then sort by Name
        Collections.sort(employees, Comparator.comparingDouble(Employee::getSalary)
                                    .thenComparing(Employee::getName));
        System.out.println("\nEmployees (Sorted by Salary and Name) : " + employees);
    }
}

输出。

Employees : [Employee{id=1010, name='Rajeev', salary=100000.0, joiningDate=2010-07-10},
Employee{id=1004, name='Chris', salary=95000.5, joiningDate=2017-03-19}, 
Employee{id=1015, name='David', salary=134000.0, joiningDate=2017-09-28},
Employee{id=1009, name='Steve', salary=100000.0, joiningDate=2016-05-18}]

Employees (Sorted by Name) : 
[Employee{id=1004, name='Chris', salary=95000.5, joiningDate=2017-03-19},
 Employee{id=1015, name='David', salary=134000.0, joiningDate=2017-09-28}, 
Employee{id=1010, name='Rajeev', salary=100000.0, joiningDate=2010-07-10},
 Employee{id=1009, name='Steve', salary=100000.0, joiningDate=2016-05-18}]

Employees (Sorted by Salary) : 
[Employee{id=1004, name='Chris', salary=95000.5, joiningDate=2017-03-19}, 
Employee{id=1010, name='Rajeev', salary=100000.0, joiningDate=2010-07-10},
 Employee{id=1009, name='Steve', salary=100000.0, joiningDate=2016-05-18}, 
Employee{id=1015, name='David', salary=134000.0, joiningDate=2017-09-28}]

Employees (Sorted by JoiningDate) : 
[Employee{id=1010, name='Rajeev', salary=100000.0, joiningDate=2010-07-10}, 
Employee{id=1009, name='Steve', salary=100000.0, joiningDate=2016-05-18},
 Employee{id=1004, name='Chris', salary=95000.5, joiningDate=2017-03-19}, 
Employee{id=1015, name='David', salary=134000.0, joiningDate=2017-09-28}]

Employees (Sorted by Name in descending order) : 
[Employee{id=1009, name='Steve', salary=100000.0, joiningDate=2016-05-18},
 Employee{id=1010, name='Rajeev', salary=100000.0, joiningDate=2010-07-10},
 Employee{id=1015, name='David', salary=134000.0, joiningDate=2017-09-28}, 
Employee{id=1004, name='Chris', salary=95000.5, joiningDate=2017-03-19}]

Employees (Sorted by Salary and Name) : 
[Employee{id=1004, name='Chris', salary=95000.5, joiningDate=2017-03-19},
 Employee{id=1010, name='Rajeev', salary=100000.0, joiningDate=2010-07-10},
 Employee{id=1009, name='Steve', salary=100000.0, joiningDate=2016-05-18}, 
Employee{id=1015, name='David', salary=134000.0, joiningDate=2017-09-28}]

4. 更多的例子

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class JLEComparatorExample {

 public static void main(String[] args) {

  List<Person> listOfPerson = new ArrayList<Person>();
  listOfPerson.add(new Person("abc", 27));
  listOfPerson.add(new Person("mno", 26));
  listOfPerson.add(new Person("pqr", 28));
  listOfPerson.add(new Person("xyz", 27));

  // Without lambda expression.
  // Sort list by age
  Comparator<Person> comparator = new Comparator<Person>() {
   @Override
   public int compare(Person o1, Person o2) {
    return o1.getAge() - o2.getAge();
   }
  };

  Collections.sort(listOfPerson, comparator);

  System.out.println(" sort persons by age in ascending order");
  for (Person person : listOfPerson) {
   System.out.println(" Person name : " + person.getName());
  }

  // Witht lambda expression.
  // Sort list by age

  Collections.sort(listOfPerson, (Person o1, Person o2) -> {
   return o1.getAge() - o2.getAge();
  });
  // Use forEach method added in java 8
  System.out.println(" sort persons by age in ascending order");
  listOfPerson.forEach(
         (person) -> System.out.println(" Person name : " + person.getName()));
 }
}

class Person {
 private String name;
 private int age;

 public Person(String name, int age) {
  super();
  this.name = name;
  this.age = age;
 }

 public String getName() {
  return name;
 }

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

 public int getAge() {
  return age;
 }

 public void setAge(int age) {
  this.age = age;
 }
}

相关文章