Сортировка списка по полям объекта, отсутствующим в некоторых объектах в списке - PullRequest
2 голосов
/ 08 июля 2019

Мне нужно отобразить список объектов учетной записи и сортировку по одному из полей объекта учетной записи (все строковые типы). Однако для некоторых полей учетной записи значение null, поэтому НЕ отображается в JSON. Это дает мне null pointer exception при сортировке по этим пропущенным полям. Как я могу заставить Comparator игнорировать пропущенное поле во время сортировки?

Я пытался Comparator.comparing(), но он работает только на общем поле (существует во всех объектах учетной записи). Если бы я попытался отсортировать поля, отсутствующие в одном из объектов учетной записи. NullPointerExceptio n бывает. Конечно, если я попытался заставить все поля отображаться с этим полем как пустое строковое значение (""), то оно работает как обычно, но выглядит не очень хорошо, поскольку этих полей может быть слишком много.

Определение счетов

@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;
    .... 

Сортировать следующий список - только тип и accountNumber являются общими

"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 в следующей строке, когда Sort на accountStatus и accountValue, которые отсутствуют в одном из аккаунтов. totalAcctList.sort(accountComparator.reversed());

Как уже упоминалось, если я сделаю все учетные записи, показывая accountStatus и accountValue например "accountStatus": "" и "accountValue":"0.0" тогда работы.

1 Ответ

5 голосов
/ 08 июля 2019

Вы можете решить использовать все null s в начале или конце списка и использовать Comparator.nullsFirst или Comparator.nullsLast соответственно:

else if (sortField.equalsIgnoreCase("accountStatus")) {
   accountComparator = 
       Comparator.comparing(Accounts::getAccountStatus, 
                            Comparator.nullsLast(Comparator.naturalOrder()));
}

РЕДАКТИРОВАТЬ:

Для accountValue вы можете использовать аналогичный подход, хотя, поскольку примитивные double s не могут быть null, вам придется сначала обработать их, прежде чем пытаться выполнить синтаксический анализ:

else if (sortField.equalsIgnoreCase("accountValue")) {    
  accountComparator = 
      Comparator.comparing((Account a) -> a.getAccountValue() == null)
                .thenComparingDouble((Account a) -> 
                                     Double.parseDouble(a.getAccountValue()));
}
...