Sorting list by an object field missing in some objects in the list

user1747980 :

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. NullPointerException 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.

Mureinik :

You could decide to have all the nulls 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 doubles 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()));
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=127972&siteId=1