Java 如何仅使用一个比较器对对象中的所有字段进行排序?

Java 如何仅使用一个比较器对对象中的所有字段进行排序?,java,comparator,Java,Comparator,如何使用单个比较器对对象中的所有字段进行排序 例如:如果我有一个Employee对象,该对象有三个字段,例如Name、Eid和Salary。我不需要编写三个比较器,即Namecomparator、eidcomarator和salarycomarator进行排序,而只需要一个比较器就可以根据我提供的字段动态排序 我只需要一个比较器就可以根据动态提供的字段进行排序,而不是编写3个比较器,即NameCompareTor、EidCompareTor和SalaryCompareTor进行排序 使用Java

如何使用单个比较器对对象中的所有字段进行排序

例如:如果我有一个
Employee
对象,该对象有三个字段,例如
Name
Eid
Salary
。我不需要编写三个比较器,即
Namecomparator
eidcomarator
salarycomarator
进行排序,而只需要一个比较器就可以根据我提供的字段动态排序

我只需要一个比较器就可以根据动态提供的字段进行排序,而不是编写3个比较器,即NameCompareTor、EidCompareTor和SalaryCompareTor进行排序

使用Java8,如果所有这些字段都有
get
方法,则可以使用

如果您想按多个条件排序(打破关系),可以使用

在这两种情况下,您只需将要排序的字段作为
函数传递
,以创建自定义
比较器
。或者,您也可以使用按各种其他条件进行排序:

Collections.sort(employees, Comparator.comparing(e -> e.getName.length()));

如果您使用的是较旧版本的Java(并且无法升级到Java 8),您可以创建自己的
函数
类和相应的通用
比较器

abstract class CompareFunction<A> {
    abstract public Comparable apply(A object);
}

class FunctionComparator<T> implements Comparator<T> {
    final CompareFunction<T> function;
    public FunctionComparator(CompareFunction<T> function) {
        this.function = function;
    }
    public int compare(T a, T b) {
        return function.apply(a).compareTo(function.apply(b));
    }
}

使用类似“按id排序,然后按姓名排序,然后按薪资排序”的方法:

public class EmployeeComparator implements Comparator<Employee> {
    public int compare(Employee e1, Employee e2) {
        if (e1 == e2) {
           return 0;
        } 
        if (e1 == null && e2 != null) {
            return -1;
        }
        if (e1 != null && e2 == null) {
            return -1;
        }
        if (e1.getId().equals(e2.getId())) {
            if (e1.getName().equals(e2.getName())) {
                if (e1.getSalary() == e2.getSalary()) {
                    return 0;
                } else {
                    return int(e1.getSalary() - e2.getSalary());
                }
            } else {
                 return e1.getName().compareTo(e2.getName());
            }
        } else {
            return e1.getId().compareTo(e2.getId());
        }
    }
}
或如下所示:

    @Override  
    public int compare(Employee e1, Employee e2) {  
        return ComparisonChain.start() 
           .compare(e1.getId(), e2.getId(), Ordering.natural().nullsLast()) 
           .compare(e1.getName(), e2.getName(), Ordering.natural().nullsLast()) 
           .compare(e1.getSalary(), e2.getSalary(), Ordering.natural().nullsLast()) 
           .result(); 
   }  
public int compare(Employee e1, Employee e2) {  
    return new CompareToBuilder().append(e1.getId(), e2.getId()).append(e1.getName(), e2.getName()).append(e1.getSalary(), e2.getSalary()).toComparison();  
}  

它很笨拙。使用一些库,比如GoogleGuava(或者Java8)。实现这一功能的不整洁代码应该是这样的:
if(o1.field1o2.field1)返回1;否则如果(o1.field2o2.field2)返回1;else if(o1.field3o2.field3)返回1;否则返回0想法是按照所需的比较顺序使用多个if-else条件(首先是最重要的字段),感谢您的回复。类似地,在Java1.6或1.7中是否有任何排序方法
public static <T> Comparator<T> createGetterComparator(Class<T> clazz, String getterName) throws Exception {
    final Method getter = clazz.getMethod(getterName);
    return new FunctionComparator<T>(new CompareFunction<T>() {
        public Comparable apply(T object) {
            try {
                return (Comparable) getter.invoke(object);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    });
}
Collections.sort(employees, createGetterComparator(Employee.class, "getSalary"));
public class EmployeeComparator implements Comparator<Employee> {
    public int compare(Employee e1, Employee e2) {
        if (e1 == e2) {
           return 0;
        } 
        if (e1 == null && e2 != null) {
            return -1;
        }
        if (e1 != null && e2 == null) {
            return -1;
        }
        if (e1.getId().equals(e2.getId())) {
            if (e1.getName().equals(e2.getName())) {
                if (e1.getSalary() == e2.getSalary()) {
                    return 0;
                } else {
                    return int(e1.getSalary() - e2.getSalary());
                }
            } else {
                 return e1.getName().compareTo(e2.getName());
            }
        } else {
            return e1.getId().compareTo(e2.getId());
        }
    }
}
    @Override  
    public int compare(Employee e1, Employee e2) {  
        return ComparisonChain.start() 
           .compare(e1.getId(), e2.getId(), Ordering.natural().nullsLast()) 
           .compare(e1.getName(), e2.getName(), Ordering.natural().nullsLast()) 
           .compare(e1.getSalary(), e2.getSalary(), Ordering.natural().nullsLast()) 
           .result(); 
   }  
public int compare(Employee e1, Employee e2) {  
    return new CompareToBuilder().append(e1.getId(), e2.getId()).append(e1.getName(), e2.getName()).append(e1.getSalary(), e2.getSalary()).toComparison();  
}