Java Stream:按 ZoneDateTime 字段排序

har*_*814 1 java lambda java-stream

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

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

      public ZonedDateTime getVisitDate() {
        return visitDate;
    }
}
Run Code Online (Sandbox Code Playgroud)

……

List<VisitViewDTO> visitViewDTOList;

visitViewDTOList.stream().sorted(Comparator.comparing(VisitViewDTO::getVisitDate).reversed()).limit(20).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

但得到了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)     
Run Code Online (Sandbox Code Playgroud)

mic*_*alk 6

您的某些 dto 对象中的访问日期似乎为空。一种解决方案是过滤掉空元素:

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

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

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