如何在Java中对对象的ArrayList进行排序

时间:2020-01-09 10:35:01  来源:igfitidea点击:

在本文中,我们将介绍如何在Java中对对象的ArrayList进行排序。在《如何用Java排序ArrayList》一文中,我们已经看到了如何对String,Date或者任何Wrapper类(Integer,Float等)进行ArrayList排序。所有这些类已经实现了Comparable接口,因此我们只需将列表传递给Collections.sort()方法即可对其进行排序。

当需要使用Java对自定义对象的ArrayList进行排序时,必须确保其对象存储在ArrayList中的类实现Comparable接口,或者已经准备好使用Comparator实现。

Comparable接口的实现将设置类的自然顺序。如果要以任何其他顺序而不是Comparable设置的自然顺序进行排序,则可以实现Comparator并使用Collections类的sort()方法,该方法将Comparator作为参数。

如果类未实现Comparable接口,并且也未指定Comparator,则将此类对象的ArrayList与sort()方法一起使用将导致编译时错误。

sort(List <T> list,Comparator <?super T> c)–根据指定Comparator的顺序对指定列表进行排序。

使用Comparable排序对象的ArrayList

在这里,我们有一个Employee类,我们想按该类的empName字段排序。然后,Employee类应实现Comparable接口并提供compareTo()方法的实现。

public class Employee implements Comparable{
  private int empId;
  private String empName;
  private int age;
  Employee(int empId, String empName, int age){
    this.empId = empId;
    this.empName = empName;
    this.age = age;
  }
  public int getEmpId() {
    return empId;
  }
  public void setEmpId(int empId) {
    this.empId = empId;
  }
  public String getEmpName() {
    return empName;
  }
  public void setEmpName(String empName) {
    this.empName = empName;
  }
  public int getAge() {
    return age;
  }
  public void setAge(int age) {
    this.age = age;
  }
    
  @Override
  public String toString() {    
    return getEmpId() + " " + getEmpName() + " " + getAge();
  }
  @Override
  public int compareTo(Employee o) {
    // Sort by empName in ascending order alphabetically
    return this.getEmpName().compareTo(o.getEmpName());
    /// sort by ascending order of age
    ///return this.getAge() - o.getAge();
  }  
}

然后,我们可以在Collections.sort()方法中传递Employee类对象的ArrayList。

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

public class SortingObjList {
  public static void main(String[] args) {
    List<Employee> empList = new ArrayList<Employee>();
    empList.add(new Employee(1, "Zhiang", 34));
    empList.add(new Employee(2, "Marie", 23));
    empList.add(new Employee(3, "Amy", 31));
    empList.add(new Employee(4, "Robbie", 45));
    empList.add(new Employee(5, "Dean", 26));
    System.out.println("**List elements**");
    for(Employee emp : empList) {
     System.out.println("" + emp);
    }
    // Sorting the list
    Collections.sort(empList);
    System.out.println("**Sorted List**");
    for(Employee emp : empList) {
      System.out.println("" + emp);
    }
  }
}

输出:

**List elements**
1 Zhiang 34
2 Marie 23
3 Amy 31
4 Robbie 45
5 Dean 26
**Sorted List**
3 Amy 31
5 Dean 26
2 Marie 23
4 Robbie 45
1 Zhiang 34

使用Comparator对对象的ArrayList进行排序

上面使用的Employee类实现Comparable并提供compareTo()方法的实现以按名称排序。这种排序顺序成为该类的自然顺序,但现在我们已受该顺序约束。如果我们现在想按年龄排序怎么办?答案是编写一个单独的方法或者实现Comparator接口的类。通过实现比较器,我们可以有多个选项进行排序。

这是更新后的Employee类,其中添加了2个Comparator实现,以按年龄排序或者以相反顺序按名称排序。

import java.util.Comparator;

public class Employee implements Comparable<Employee>{
  private int empId;
  private String empName;
  private int age;
  Employee(int empId, String empName, int age){
    this.empId = empId;
    this.empName = empName;
    this.age = age;
  }
  public int getEmpId() {
    return empId;
  }
  public void setEmpId(int empId) {
    this.empId = empId;
  }
  public String getEmpName() {
    return empName;
  }
  public void setEmpName(String empName) {
    this.empName = empName;
  }
  public int getAge() {
    return age;
  }
  public void setAge(int age) {
    this.age = age;
  }
    
  @Override
  public String toString() {    
    return getEmpId() + " " + getEmpName() + " " + getAge();
  }
  @Override
  public int compareTo(Employee o) {
    // Sort by empName in ascending order alphabetically
    return this.getEmpName().compareTo(o.getEmpName());
    /// sort by ascending order of age
    ///return this.getAge() - o.getAge();
  }
    
  static Comparator<Employee> empCompByAge = new Comparator<Employee>() {
    @Override
    public int compare(Employee emp1, Employee emp2) {
        return emp1.getAge() - emp2.getAge();
    }        
  };

  static Comparator<Employee> empCompByNameDesc = new Comparator<Employee>() {
    @Override
    public int compare(Employee emp1, Employee emp2) {
        return emp2.getEmpName().compareTo(emp1.getEmpName());
    }        
  }; 
}

然后,我们可以将这些Comparator实现与sort()方法一起传递,以获取所需的顺序。

public class SortingObjList {
  public static void main(String[] args) {
    List<Employee> empList = new ArrayList<Employee>();
    empList.add(new Employee(1, "Zhiang", 34));
    empList.add(new Employee(2, "Marie", 23));
    empList.add(new Employee(3, "Amy", 31));
    empList.add(new Employee(4, "Robbie", 45));
    empList.add(new Employee(5, "Dean", 26));
    System.out.println("**List elements**");
    for(Employee emp : empList) {
      System.out.println("" + emp);
    }
    // Sorting the list by employee age
    Collections.sort(empList, Employee.empCompByAge);
    System.out.println("**Sorted List**");
    for(Employee emp : empList) {
      System.out.println("" + emp);
    }
         
    // Sorting the list by employee name in reverse order
    Collections.sort(empList, Employee.empCompByNameDesc);
    System.out.println("**Sorted List**");
    for(Employee emp : empList) {
      System.out.println("" + emp);
    }
  }
}

输出:

**List elements**
1 Zhiang 34
2 Marie 23
3 Amy 31
4 Robbie 45
5 Dean 26
**Sorted List by age**
2 Marie 23
5 Dean 26
3 Amy 31
1 Zhiang 34
4 Robbie 45
**Sorted List**
1 Zhiang 34
4 Robbie 45
2 Marie 23
5 Dean 26
3 Amy 31