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