Instead of writing 3 comparator's i.e., Namecomparotor, Eidcomparotor and Salarycomparotor for sorting, I need only only one comparotor that can sort based on the filed I provide dynamically.
Using Java 8, and if all those fields have a get method, you can use Comparator.comparing
Collections.sort(employees, Comparator.comparing(Employee::getSalary);
And if you want to sort by multiple criteria (to break ties), you can use thenComparing
Collections.sort(employees, Comparator.comparing(Employee::getSalary)
.thenComparing(Employee::getName)
.thenComparing(Employee::getId));
In both cases, you just pass the field to sort by as a Function to create a custom Comparator. Alternatively, you can also use a lambda expression to sort by all kinds of other criteria:
Collections.sort(employees, Comparator.comparing(e -> e.getName.length()));
In case you are using an older version of Java (and can not upgrade to Java 8), you could make your own Function class and an according generic Comparator:
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));
}
}
Usage:
Collections.sort(employees, new FunctionComparator<Employee>(new CompareFunction<Employee>() {
public Comparable apply(Employee object) {
return object.getSalary();
};
}));
Or combine it with Java Reflextion to create such a comparator based on the name of a getter method:
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;
}
}
});
}
Usage:
Collections.sort(employees, createGetterComparator(Employee.class, "getSalary"));
if (o1.field1 < o2.field2) return -1; else if (o1.field1 > o2.field1) return 1; else if (o1.field2 < o2.field2) return -1; else if (o1.field1 > o2.field2) return 1; else if (o1.field3 < o2.field3) return -1 else (o1.field3 > o2.field3) return 1; else return 0;The idea is to use multiple if-else condition in the desired comparison order (most important field first)