首页 > 解决方案 > 按列表中某些对象中缺少的对象字段对列表进行排序

问题描述

我需要显示帐户对象列表并在其中一个帐户对象字段(所有字符串类型)上进行排序。但是,某些帐户字段值未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在以下行上,当Sort打开时accountStatusaccountValue其中一个帐户中缺少哪些。 totalAcctList.sort(accountComparator.reversed());

如前所述,如果我让所有帐户都显示accountStatusaccountValue例如“accountStatus”:“”,"accountValue":"0.0"那么它就可以工作。

标签: javasortingnullcomparator

解决方案


您可以决定将所有nulls 放在列表的开头或结尾,并分别使用Comparator.nullsFirstor 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()));
}

推荐阅读