按列表中某些对象中缺少的对象字段对列表进行排序

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

我需要显示一个帐户对象列表并在其中一个帐户对象字段(所有字符串类型)上排序。但是,某些帐户字段值为 null,因此未显示在 JSON 中。在对那些缺失的字段进行排序时,它给了我一个 null pointer exception。如何让 Comparator 在排序过程中忽略缺失的字段?

我试过 Comparator.comparing() 但它只适用于公共字段(存在于所有帐户对象中)。如果我尝试对其中一个帐户对象中缺少的字段进行排序。 NullPointerException 发生了。当然,如果我试图强制所有字段显示为空字符串值 (""),那么它会正常工作,但它看起来不太好,因为这些字段可能太多了。

帐户定义

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

对以下列表进行排序 - 只有 type 和 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 在下一行当 SortaccountStatusaccountValue 其中一个帐户中缺少。 totalAcctList.sort(accountComparator.reversed());

如前所述,如果我让所有帐户都显示 accountStatus 并且 accountValue 例如 "accountStatus":"" 和 "accountValue":"0.0" 那么它 有效。

您可以决定将所有 null 放在列表的开头或结尾,并分别使用 Comparator.nullsFirst or Comparator.nullsLast

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

编辑:

对于 accountValue 你可以采用类似的方法,尽管由于原始 doubles 不能是 null,你必须先处理它们,然后再尝试解析:

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