Java Stream:按ZoneDateTime字段排序

时间:2019-05-18 07:39:54

标签: java lambda lightweight-stream-api

我想按ZoneDateTime字段以相反的顺序对列表进行排序,限制为20

    public class VisitViewDTO implements Serializable {
      private ZonedDateTime visitDate;
      private int count;

      public ZonedDateTime getVisitDate() {
        return visitDate;
    }
}

.....

List<VisitViewDTO> visitViewDTOList;

visitViewDTOList.stream().sorted(Comparator.comparing(VisitViewDTO::getVisitDate).reversed()).limit(20).collect(Collectors.toList());

但是得到了NPE:

java.lang.NullPointerException: null
    at java.time.chrono.ChronoZonedDateTime.compareTo(ChronoZonedDateTime.java:570)
    at java.time.chrono.ChronoZonedDateTime.compareTo(ChronoZonedDateTime.java:121)
    at java.util.Comparator.lambda$comparing$77a9974f$1(Comparator.java:469)
    at java.util.Collections$ReverseComparator2.compare(Collections.java:5178)
    at java.util.TimSort.countRunAndMakeAscending(TimSort.java:356)
    at java.util.TimSort.sort(TimSort.java:220)
    at java.util.Arrays.sort(Arrays.java:1512)     

2 个答案:

答案 0 :(得分:2)

正如michalk正确指出的那样,可能有一些带有visitDate=null的元素可能会导致NullPointerException 因此,您可能要过滤非null值,

 visitViewDTOList.stream().filter(ele-> Objects.nonNull(ele.getVisitDate()))
                .sorted(Comparator.comparing(VisitViewDTO::getVisitDate).reversed())
                .limit(20).collect(Collectors.toList());

答案 1 :(得分:2)

您的某些dto对象中的visitDate似乎为空。一种解决方案是过滤出null元素:

visitViewDTOList.stream()
                .filter(visitViewDTO -> visitViewDTO.getVisitDate() != null)
                .sorted(Comparator.comparing(VisitViewDTO::getVisitDate).reversed())
                .limit(20)
                .collect(Collectors.toList());

或使用比较器,该比较器将首先或最后处理空值-nullsFirstnullsLast

visitViewDTOList.stream()
                .sorted(Comparator.comparing(VisitViewDTO::getVisitDate, Comparator.nullsFirst(Comparator.reverseOrder())))
                .limit(20)
                .collect(Collectors.toList());