I have a class with multiple properties I want it sorted by. Currently I am sorting by Name like this:
Collections.sort(rowItems, new Comparator() {
public int compare(Object o1, Object o2) {
SearchRowItem p1 = (SearchRowItem) o1;
SearchRowItem p2 = (SearchRowItem) o2;
return p1.getName().compareToIgnoreCase(p2.getName());
}
});
But I also want to sort by LastName secondarily to Name (so if names are the same sort by LastName second). How do I combine my code below with my first sort to get the outcome I described?
Collections.sort(rowItems, new Comparator() {
public int compare(Object o1, Object o2) {
SearchRowItem p1 = (SearchRowItem) o1;
SearchRowItem p2 = (SearchRowItem) o2;
return p1.getLastName().compareToIgnoreCase(p2.getLastName());
}
});
A simple Comparator that first compares the name and then the lastName will work with the Collections.sort method.
From the JavaDoc:
Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
So, here is the example of the Comparator that compares on two properties:
Collections.sort(rowItems, new Comparator<SearchRowItem>() {
@Override
public int compare(final SearchRowItem o1, final SearchRowItem o2) {
int compare = o1.getName().compareToIgnoreCase(o2.getName());
if (compare != 0) {
return compare;
}
return o1.getLastName().compareToIgnoreCase(o2.getLastName());
}
});
However, there are other alternatives. Java 8 introduced streams where sorting integrates nicely. Together with the new methods Comparator.comparing and the thenCompare a nice stream can be created like this.
final List<SearchRowItem> collect = rowItems.stream()
.sorted(
Comparator.comparing(SearchRowItem::getName, String::compareToIgnoreCase)
.thenComparing(SearchRowItem::getLastName, String::compareToIgnoreCase))
.collect(Collectors.toList());
Note that the latter does not sort the original List but creates a new sorted list.
If getName() returns 0 it means that both objects have the same name - only then should you use getLastName():
Collections.sort(rowItems, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
SearchRowItem p1 = (SearchRowItem) o1;
SearchRowItem p2 = (SearchRowItem) o2;
int nameComp = p1.getName().compareToIgnoreCase(p2.getName());
if (nameComp != 0) {
return nameComp;
}
return p1.getLastName().compareToIgnoreCase(p2.getLastName());
}
});
EDIT:
The answer above follows the OP's style. However, if possible, you should use generics to clean up the code:
Collections.sort(rowItems, new Comparator<SearchRowItem>() {
@Override
public int compare(SearchRowItem p1, SearchRowItem p2) {
int nameComp = p1.getName().compareToIgnoreCase(p2.getName());
if (nameComp != 0) {
return nameComp;
}
return p1.getLastName().compareToIgnoreCase(p2.getLastName());
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With