欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Comparator多级排序

程序员文章站 2022-04-17 09:07:32
...

       JDK里的Comparator方法为用户提供了自定义排序规则的接口,而我们在实际使用是一般也只是用了一个排序维度,本文介绍下多级或多个维度的排序需求下的接口实现。

       我们假设一个雇员对象,包含级别、工资和入职年份(为了简单,这些属性写成 public),代码如下:

 

public Class Employee {
 
    public int level;  //级别
    public int salary; //工资
    public int years;  //入职年数
 
}

       现在我需要做一个这样的雇员列表,首先级别最高的排在前面,如果级别相等,那么按工资排序,工资高的排在前面,如果工资相当则按入职年数排序,入职时间最长的排在前面。

       因为雇员列表是在内存中的一个 List<Employee> 对象,现在要对这个 List 中的雇员按上面的要求进行排序 Collections.sort(employeeList, comparator),那么这个 Comparator 应该怎么写呢?

下面这种肯定是不对的

Comparator<Employee> cp_by_default = new Comparator<Employee>(){
    @Override
    public int compare(Employee a1, Employee a2) {
        int a = a2.level - a1.level;
        if(a > 0)
            return a;
        a = a2.salary - a1.salary;
        if(a > 0)
            return a;
        return a2.years - a1.years;
    }       
};

 

 正确参考代码写法如下

package net.oschina.tester;
 
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
 
/**
 * 多个排序条件测试
 */
public class Employee {
 
    public static void main(String[] args) {
        List<Employee> objs = new ArrayList<Employee>(){{
            add(new Employee(5,3,5000,2));
            add(new Employee(1,9,10000,10));
            add(new Employee(4,5,8000,6));
            add(new Employee(2,9,12000,7));
            add(new Employee(6,1,2000,1));
            add(new Employee(3,5,8000,12));
        }};
        Collections.sort(objs, comparator);
        System.out.println("No\tLevel\tSalary\tYears\n=============================");
        for(Employee a : objs)
            System.out.printf("%d\t%d\t%d\t%d\n",a.id,a.level,a.salary,a.year);
    }
 
    public Employee(int id, int level, int salary, int year){
        this.id = id;
        this.level = level;
        this.salary = salary;
        this.year = year;
    }
     
    public int id;
    public int level;
    public int salary;
    public int year;
 
    private final static Comparator<Employee> comparator = new Comparator<Employee>(){
        @Override
        public int compare(Employee a1, Employee a2) {
            int cr = 0;
            int a = a2.level - a1.level;
            if(a != 0)
                cr = (a>0)?3:-1;
            else{
                a = a2.salary - a1.salary;
                if(a != 0)
                    cr = (a>0)?2:-2;
                else{
                    a = (int)(a2.year - a1.year);
                    if(a != 0)
                        cr = (a>0)?1:-3;
                }
            }
            return cr;
        }       
    };
     
}

 上面参考方法给出了3级排序规则下的接口实现方法,2级或3级以上的接口实现方式类似。