Reputation: 223
How to to sort list of objects based on field which can be null
?
I am trying to do it in following way using Comparator
interface and collections sort method.
The class is CustomClass
and the field on which sorting is to be done is createDate
Comparator comparator=new Comparator<CustomClass>(){
public int compare(CustomClass o1, CustomClass o2) {
if(o1.getCreateDate()==null && o2.getCreateDate()==null){
return 0;
}
else if(o1.getCreateDate()==null && o2.getCreateDate()!=null){
return 1;
}
else if(o1.getCreateDate()!=null && o2.getCreateDate()==null){
return -1;
}
else{
if(o1.getCreateDate().equals(o2.getCreateDate())){
return 0;
}
else if(o1.getCreateDate().after(o2.getCreateDate())){
return 1;
}
else{
return -1;
}
}
}
};
Is there a better way to do it?
Upvotes: 5
Views: 6106
Reputation: 312116
Assuming getCreateDate()
returns an instance of java.util.Date
, you can clean up the code a bit. The compareTo
's method's contract specifies that it throws a NullPointerException
if a date is compared to null
(like any Comparable
class should do), so you'll have to handle those directly. However, if both are non-null
, you shouldn't reimplement the comparing logic, but rely on Date
's implementation:
Comparator<CustomClass> comparator = new Comparator<CustomClass>(){
public int compare(CustomClass o1, CustomClass o2) {
if (o1.getCreateDate() == null && o2.getCreateDate() == null) {
return 0;
}
else if (o1.getCreateDate() == null && o2.getCreateDate() != null) {
return 1;
}
else if (o1.getCreateDate() != null && o2.getCreateDate() == null) {
return -1;
}
else{
// Just use java.util.Date's logic:
return o1.getCreateDate().compareTo(o2.getCreateDate());
}
}
};
EDIT:
This is quite an old question, but just to complete the picture, in Java 8, the Comparator
class itself can do the heavy lifting for you:
Comparator<CustomClass> comparator =
Comparator.comparing(CustomClass::getCreateDate,
Comparator.nullsLast(Comparator.naturalOrder()));
Upvotes: 9
Reputation: 16625
If you're willing to use Google Guava, then you can use ComparisonChain
and Ordering
to make things more succinct.
public int compare(CustomClass o1, CustomClass o2)
{
return ComparisonChain.start()
.compare(o1.getCreateDate(), o2.getCreateDate(), Ordering.natural().nullsLast())
.result();
}
Upvotes: 6
Reputation: 77226
You do need all of that to ensure that the null
values always sort to the end of the list and otherwise you sort by date. You could simplify your code a bit by delegating to the built-in compareTo
or by using a declarative Guava Ordering
.
Upvotes: 0