Java/Sort 2 attributes with collection sort
Expert: Neal Ziring - 3/16/2007
QuestionHi,
I solved the problem to sort the Employee first based on Employee Id and then based on Employee Name...I have got 4 class to do this...
1) my Employee calss,which has the Get/Set methods.
2) my EmployeeNameCompare class which implements the Comparator and in my compare methods i'm sorting based on Name..
public int compare(Object obj1, Object obj2) {
String name = ((Employee) obj1).getName();
String name1 = ((Employee) obj2).getName();
return name.compareTo(name1);
}
3) my EmployeeIdCompare class which implements the Comparator and in my compare methods i'm sorting based on ID..
4) And finally my Utility calss which calls the Collection.Sort(list,new EmployeeNameCompare() );
Collection.Sort(list,new EmployeeIdCompare () );
But my problem is if i need to sort on the basis of age,sex,place i need to have 3 more Comparator class for these.
Is there any way to reduce the number of comparatorclass and sort as many atributes i want. I want to make the comparatorclass generic.
AnswerMary,
You can easily combine the results from several Comparators
for an object class into one Comparator.
First, create a Comparator class for each
different aspect of the Employee class that you might need.
For example:
public class EmployeeAgeComparator
implements Comparator
{
public int compare(Object o1, Object o2) {
int age1 = ((Employee)o1).getAge();
int age2 = ((Employee)o2).getAge();
if (age1 < age2) return -1;
if (age2 < age1) return 1;
return 0;
}
}
Once you've got EmployeeIdComparator, EmployeeNameComparator and all the rest, then use this class:
public class MultiComparator
implements Comparator
{
Vector comparators;
public MultiComparator() {
comparators = new Vector();
}
public void addComparator(Comparator c) {
comparators.add(c);
}
public void removeComparator(Comparator c) {
comparators.remove(c);
}
public int compare(Object obj1, Object obj2) {
int result, i;
Comparator c;
result = 0;
for(i = 0; i < comparators.size(); i++) {
c = (Comparator)(comparators.elementAt(i));
result = c.compare(obj1,obj2);
if (result != 0) break;
}
return result;
}
}
Now that you have the multi-comparator, and individual
comparators for all the fields, you can create a comparator
that has any properties you want. For example, to sort
on EmployeeID, Name, and Age, in that order, you would do
this:
MultiComparator mc;
mc = new MultiComparator();
mc.add(new EmployeeIdComparator());
mc.add(new EmployeeNameComparator());
mc.add(new EmployeeAgeComparator());
Collections.sort(list, mc);
The solution I have outlined above is the most general and
the most flexible. You can reduce the number of comparator
classes, but it will make your solution less flexible. For
example:
public class EmployeeNameAndAgeComparator() {
public int compare(Object o1, Object o2) {
int result;
Employee e1, e2;
e1 = (Employee) o1;
e2 = (Employee) o2;
result = e1.getName().compareTo(e2.getName());
if (result != 0) return result;
if (e1.getAge() < e2.getAge()) return -1;
if (e2.getAge() < e1.getAge()) return 1;
return 0;
}
}
There is no other simple way to make a comparator that
sorts on many attributes. There are complex ways to do
this, but they depend on the structure and value ranges
of the attributes.
Hope this helps...
...nz