A couple of new features in Java 5 are the additions of generics and varargs. We use generics a lot when returning a list from our DAOs but I've never had to implement a method that accepted varargs until I implemented this parent reviews page.
This is a typical page where a user may sort by date or by rating. Another feature is that a principal's review for a school always comes first. So the sorting is like so:
- By Principal, then date descending
- By Principal, then date ascending
- By Principal, then rating, then descending
First thing I needed to do was create a couple of comparators. I used the static final comparator approach that that Josh Block talks about in Effective Java. I'll demonstrate with a baseball class. The nice thing about the composite comparator is that now I can create a comparator based on hr,rbi, and anything else I wanted to add later like sb, runs, etc.
Example:
public class BaseBallPlayer {
private int _rbi;
private int _hr;
public BaseBallPlayer(int rbi, int hr) {
_rbi = rbi;
_hr = hr;
}
public static final Comparator HR_COMPARATOR = new Comparator<BaseBallPlayer>() {
public int compare(BaseBallPlayer o1, BaseBallPlayer o2) {
return o1.getRbi() - o2.getRbi();
}
};
public static final Comparator RBI_COMPARATOR = new Comparator<BaseBallPlayer>() {
public int compare(BaseBallPlayer o1, BaseBallPlayer o2) {
return o1.getHr() - o2.getHr();
}
};
public int getHr() {
return _hr;
}
public int getRbi() {
return _rbi;
}
}
public class GenericComparator {
public static <T>Comparator<T> createComparator(final Comparator<T>... c) {
return new Comparator<T>() {
public int compare(T r1, T r2) {
int result = 0;
for (Comparator<T> comp : c) {
result = comp.compare(r1, r2);
if (result != 0) {
break;
}
}
return result;
}
};
}
}
Comparator<BaseBallPlayer> HR_RBI_COMPARATOR = GenericComparator.<BaseBallPlayer>createComparator(
BaseBallPlayer.HR_COMPARATOR, BaseBallPlayer.RBI_COMPARATOR);