Reputation: 255
I need to display a list of account objects and sorting on one of the account object fields (all string type). However, some account fields value is null
so NOT showing in the JSON
. It gives me a null pointer exception
when sorting on those missing field. How can I have the Comparator
ignore the missing field during sorting ?
I tried Comparator.comparing()
but it only works on the common field (existing in all account object). If I tried to sort on the field missing in one of the account objects. NullPointerExceptio
n happens. Of course, if I tried to force all fields show up with those field as empty string value ("") then it works as normal but it does not look good since it might be too many of those fields.
Accounts definition
@JsonInclude(Include.NON_NULL)
private String type;
@JsonInclude(Include.NON_NULL)
private String accountNumber;
@JsonInclude(Include.NON_NULL)
private String accountStatus;
@JsonInclude(Include.NON_NULL)
private String accountValue;
....
Sort following list - only type and accountNumber are common
"accounts": [
{
"type": "type1",
"accountNumber": "1816227",
"accountStatus": "cancelled",
},
{
"type": "type2",
"accountNumber": "2816218",
"accountValue": "19438.60",
},
{
"type": "type3",
"accountNumber": "2209890",
"accountStatus": "inactive",
"accountValue": "4343.410",
}
if (sortField.equalsIgnoreCase("type")) {
accountComparator = Comparator.comparing(Accounts::getType);
}else if(sortField.equalsIgnoreCase("accountNumber")) {
accountComparator = Comparator.comparing(Accounts::getAccountNumber);
}else if(sortField.equalsIgnoreCase("accountStatus")) {
accountComparator = Comparator.comparing(Accounts::getAccountStatus);
}else if(sortField.equalsIgnoreCase("accountValue")) {
accountComparator = Comparator.comparingDouble(acc ->
Double.valueOf(acc.getAccountValue()));
}
......
Nullpointer exception
on following line when Sort
on accountStatus
and
accountValue
which are missing in one of the accounts.
totalAcctList.sort(accountComparator.reversed());
As mentioned, if I make all accounts showing accountStatus
and
accountValue
such as "accountStatus":"" and "accountValue":"0.0"
then it
works.
Upvotes: 2
Views: 360
Reputation: 312126
You could decide to have all the null
s at the beginning or the end of the list, and use Comparator.nullsFirst
or Comparator.nullsLast
respectively:
else if (sortField.equalsIgnoreCase("accountStatus")) {
accountComparator =
Comparator.comparing(Accounts::getAccountStatus,
Comparator.nullsLast(Comparator.naturalOrder()));
}
EDIT:
For accountValue
you could take a similar approach, although since primitive double
s can not be null
, you'll have to handle them first, before attempting to parse:
else if (sortField.equalsIgnoreCase("accountValue")) {
accountComparator =
Comparator.comparing((Account a) -> a.getAccountValue() == null)
.thenComparingDouble((Account a) ->
Double.parseDouble(a.getAccountValue()));
}
Upvotes: 5