Here's a tutorial about ordering objects: http://java.sun.com/docs/books/tutorial/collections/interfaces/order.html. Although I will give some examples, I would recommend to read it anyway.
You have basically 2 options: 1) let Contact
implement Comparable
. Assume that you want to sort on name
by default, then do:
public class Contact implements Comparable<Contact> {
private String name; // +getter +setter.
public int compareTo(Contact other) {
return name.compareTo(other.name);
}
}
so that you can just do
List<Contact> contacts = new ArrayList<Contact>();
// Fill it.
Collections.sort(contacts);
2) Create a more specific Comparator
so that you have a bit more external control over the ordering over contacts:
List<Contact> contacts = new ArrayList<Contact>();
// Fill it.
// Now sort by address instead of name (default).
Collections.sort(contacts, new Comparator<Contact>() {
public int compare(Contact one, Contact other) {
return one.getAddress().compareTo(other.getAddress());
}
});
An extension of option two, if you sort by different fields at different times, is to define multiple Comparator
s, and use them by name rather than creating them when used...
public class Contact {
private String name; // +getter +setter.
private String phone; // +getter +setter.
private String email; // +getter +setter.
public static Comparator COMPARE_BY_ADDRESS = new Comparator<Contact>() {
public int compare(Contact one, Contact other) {
return one.getAddress().compareTo(other.getAddress());
}
}
public static Comparator COMPARE_BY_PHONE = new Comparator<Contact>() {
public int compare(Contact one, Contact other) {
return one.phone.compareTo(other.phone);
}
}
public static Comparator COMPARE_BY_EMAIL = new Comparator<Contact>() {
public int compare(Contact one, Contact other) {
return one.email.compareTo(other.email);
}
}
}
then you can do things like:
List<Contact> contacts = new ArrayList<Contact>();
// Fill it.
// Then when you want to:
Collections.sort(contacts, Contact.COMPARE_BY_ADDRESS);
// Later:
Collections.sort(contacts, Contact.COMPARE_BY_PHONE);
// Still later:
Collections.sort(contacts, Contact.COMPARE_BY_EMAIL);
And to cream the top off, you could consider to use a "generic javabean comparator":
class BeanComparator implements Comparator<Object> {
private String getter;
public BeanComparator(String field) {
this.getter = "get" + field.substring(0, 1).toUpperCase() + field.substring(1);
}
public int compare(Object o1, Object o2) {
try {
if (o1 != null && o2 != null) {
o1 = o1.getClass().getMethod(getter, new Class[0]).invoke(o1, new Object[0]);
o2 = o2.getClass().getMethod(getter, new Class[0]).invoke(o2, new Object[0]);
}
} catch (Exception e) {
// If this exception occurs, then it is usually a fault of the developer.
throw new RuntimeException("Cannot compare " + o1 + " with " + o2 + " on " + getter, e);
}
return (o1 == null) ? -1 : ((o2 == null) ? 1 : ((Comparable<Object>) o1).compareTo(o2));
}
}
which you can use as follows:
// Sort on "email" field of the Contact bean.
Collections.sort(contacts, new BeanComparator("email"));
(as you see in the code, possibly null fields are already covered to avoid NPE's during sort)